Commit Graph
89 Commits
Author SHA1 Message Date
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 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 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 ec3bacc9bd fix(chat): hide ignored provider information (#14929)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Task and agent chats show agent progress and problems that need
attention.
> - Codex also sends account, skill, and unrelated thread notifications.
> - The runner correctly ignores that information but reports it as a
warning.
> - Chat then shows an internal diagnostic as an actionable provider
notice.
> - This pull request keeps the diagnostic in run logs and removes it
from chat.
> - Real provider warnings, errors, and agent replies remain visible.

## Linked Issues or Issue Description

**What happened?**

Chat showed “Received a provider update” and a warning with the text
“ignored
unrelated provider information”. Its details said “User Actionable: Yes”
even
though no user action was needed. Saved conversations retained the same
noise.

**Expected behavior**

Keep ignored provider information in the run log. Do not show it as chat
activity
or a user warning. Preserve real warnings and errors.

**Steps to reproduce**

1. Start a conversation with the native Codex runner.
2. Have the provider send an account update, skill change, or unrelated
thread
   notification during the turn.
3. Inspect live chat and reload its saved history.

The regression tests also reproduce the old stored notice without a live
account.

**Paperclip version or commit**

Source implementation on master at `e00d10d5d`. The duplicate search
found no
open PR for this fix. Related prior work: #13109 improved
provider-notice
presentation. #12367 added Codex thread normalization. This change
addresses
the internal information that those paths still projected as chat
warnings.

**Deployment mode**

Native Paperclip Runner with the Codex app-server provider. The issue
was seen
in hosted chat and can be reproduced with local provider fixtures.

## What Changed

- Map ignored unrelated Codex information to `harness.diagnostic` in the
Rust
  and TypeScript normalizers.
- Retain a bounded allowlist of redacted provider method and thread/turn
identifiers.
- Use the same Unicode character limit and truncation marker in both
normalizers.
- Share the text redactor through a pure helper. Keep provider
connection code
  out of the standalone demo's source closure.
- Omit that diagnostic and the matching legacy notice from live chat.
- Omit the matching legacy notice from saved chat history.
- Test diagnostic retention, account-notification integration, live and
saved
  chat, and continued visibility of real warnings, errors, and replies.
- Document the local run-log event and historical display behavior.

## Verification

- Passed: 68 tests in the two affected UI transcript suites.
- Passed: 60 TypeScript tests across provider events, transport
behavior, and
  the standalone demo boundary.
- Passed: 13 Rust provider-event tests and the Codex
account-notification
  integration test.
- Passed: `pnpm check:token-gates` and Cargo formatting checks.
- Passed: full `pnpm build` and `pnpm -r typecheck`. After the review
fix,
the provider package build, typecheck, and both provider-event suites
passed again.
- Full local `pnpm test:run` failed: 608 files / 10,904 tests passed, 30
server
suites failed, and 104 files / 4,012 tests were skipped. Most failures
were
  embedded PostgreSQL startup errors. Two tests timed out in
`heartbeat-comment-wake-batching` and
`workspace-git-snapshot-streaming`.
  PostgreSQL startup also failed in `heartbeat-run-event-sequencing` and
`native-finalization-migration`. These server files are unchanged by
this PR.
Isolated heartbeat reruns were skipped locally. The stable test script
stopped
  after this general-server group, so later groups did not run locally.
- The original review thread is resolved. Greptile is 5/5 on current
head
  `683dab7cce57187c57e84c83f5e9da4ad75c9c04`.
- All current-head CI gates passed, including the full
server/chat/workspace
test matrix, Rust and TypeScript runner suites, browser E2E, build,
typecheck,
and release canary. [CI
run](https://github.com/paperclipai/paperclip/actions/runs/37021330663).
- Replay the exact old warning in either transcript adapter. It must
produce
no chat row. A genuine provider warning or error must still produce a
row.

## Risks

- Low risk. The display filter matches one diagnostic code or the
complete
  legacy warning shape. Other provider notices remain visible.
- New ignored-information events use the existing harness-diagnostic
event
type. They retain diagnostic evidence without original account payloads.
- No database migration, API permission, provider execution, or recovery
  behavior changes. This affects the local run log, not Telemetry or
  OpenTelemetry exports.

## Model Used

OpenAI Codex, GPT-6. The exact backend model ID and context-window size
are
not exposed in this session. Used reasoning, repository inspection, code
editing, tool use, and test 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 the affected tests locally and they pass (the broad
local run has PostgreSQL startup errors and timeouts documented above;
the full CI matrix passed)
- [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 09:59:34 -05:00
DottaandPaperclip 408f70e69f fix(runner): preserve stock Codex base instructions (#14920)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - The native Runner connects Paperclip tasks to Codex app-server.
> - Paperclip passed its runtime context as `baseInstructions`.
> - That field replaces the stock Codex base prompt.
> - This pull request sends the same Paperclip context as additive
developer instructions.
> - Codex keeps its stock prompt and still receives Paperclip task
instructions and tools.

## Linked Issues or Issue Description

**What happened?**

The native Codex driver and Rust provider sent Paperclip context through
`baseInstructions` on thread start and resume. Codex used this text in
place of its stock base instructions. Direct-chat resume also sent an
empty replacement base. The Runner Lab session path used the same
replacement field.

**Expected behavior**

Codex should retain its stock base prompt. Paperclip should add its
runtime context through `developerInstructions`. Other provider facades
should retain their current instruction handling.

**Steps to reproduce**

1. Create a native Codex session through Paperclip Runner.
2. Inspect the `thread/start` request in the native provider trace.
3. Resume the session and inspect `thread/resume`.
4. Before this fix, these paths set `baseInstructions`. After this fix,
the Codex paths set `developerInstructions` and omit `baseInstructions`.

**Paperclip version or commit**

Reproduced against master at `cad26c6bfb736039c8ed5743da650a44792a083c`.

**Deployment mode**

Built from source. Native Codex app-server and runnerd paths. A local
protocol probe used codex-cli 0.153.4 and a localhost Responses stub.

No duplicate fix or matching public issue was found in the GitHub
search.

## What Changed

- Send additive developer instructions on Codex start and resume in the
TypeScript driver, Rust provider, and Runner Lab session path.
- Carry the additive fragment through runnerd, including runtime asset
path mapping.
- Preserve existing instruction fields for other provider facades,
including OpenCode.
- Add start/resume/direct-chat regression coverage and check the actual
Rust provider request.
- Document the historical option and trace field names. Record progress
and follow-ups in the working checklist.

## Verification

- `pnpm -r typecheck` — passed.
- `pnpm build` — passed.
- Targeted Codex driver lifecycle, driver, and live-session Vitest
suites — 139 tests passed.
- `cargo test --manifest-path
packages/paperclip-runner/runner/Cargo.toml --locked -p
paperclip-runner-core --test codex_provider` — 91 passed, 2 ignored
subprocess helpers.
- Real app-server probe: a localhost Responses stub captured identical
14,732-character stock base instructions on fresh start and cold resume.
Both requests retained the Paperclip marker in developer input. Both
stub turns completed. No paid inference was used.
- Runnerd transport Vitest suite — 182 tests passed.
- The initial `pnpm test:run` attempt reported local dependency-loading,
embedded PostgreSQL startup, and macOS `/var` versus `/private/var` path
failures. It was stopped after those failures. Loading-suite reruns
passed 1,428 tests after the build; native interaction/finalization
reruns passed 38 tests. A seven-suite diagnostic rerun passed 463 tests
and isolated the remaining path and PostgreSQL setup failures.
- With `TMPDIR=/private/tmp`, workspace, gateway, interaction, and
attachment suites passed all 356 tests. The remaining environment-image
and native-session-resumption suites passed all 44 tests with the same
canonical temp path. All affected suites passed on rerun. The original
full local command was stopped after failures and is not claimed as
passing.
- All 55 PR checks passed at `83281439456181396f3707eecda5d2ebc90bd14d`.
Greptile scored 5/5 with no open review threads.
- No paid live campaign or Product E2E browser suite was run. This
change has protocol and regression coverage; it does not claim improved
task quality.

## Risks

- Stock Codex behavior may differ from behavior under the previous
Paperclip replacement prompt. Restoring that behavior is the intended
change.
- Existing Codex threads retain their saved replacement base prompt.
They need a provider session reset to receive the stock base. This PR
does not reset active sessions or alter recovery rules.
- The legacy `baseInstructions` option and trace field names remain for
compatibility. They now describe the additive Paperclip fragment for
Codex.
- The separate Codex-through-ACP dependency patch remains a follow-up in
the harness coverage checklist. This PR covers native app-server
execution.

## Model Used

OpenAI Codex, GPT-6. The exact runtime model variant and context window
are not exposed in this session. Used reasoning, repository inspection,
code editing, shell execution, and test 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)
- [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 08:53:47 -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
DottaandPaperclip 94e8dec56b fix(runner): preserve tool outcomes through shutdown and restart (#14734)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - The runner sends authorized tool calls to the server and saves their
results.
> - A provider turn can stop while a server write is still running.
> - The old shutdown path invented a failed result that could conflict
with the real result.
> - Truncated execution input and incomplete recovery records made the
failure harder to diagnose.
> - This pull request preserves exact inputs and actual outcomes through
shutdown and restart.
> - Tests force the race and crash boundaries so safe retries do not
repeat writes.

## Linked Issues or Issue Description

**What happened?**

Stopping a turn during a server tool call could record a false failure,
then reject the actual result as a conflict. The diagnostic input
formatter could truncate instruction content before execution. A crash
during saved-result delivery could leave that delivery permanently
indeterminate. Cleanup could hide the first failure, and a retry could
overwrite earlier run logs.

**Expected behavior**

Keep dispatched tools pending until their actual result is known.
Preserve accepted input bytes. Accept identical result delivery without
failing the task. Reject conflicting results with enough evidence to
diagnose them. Recover saved-result delivery without repeating the
business operation.

**Steps to reproduce**

1. Hold an instruction update at the filesystem commit barrier.
2. Stop its provider turn before the server returns the result.
3. Release the write, deliver its result, and replay the same result.
4. Repeat with a restart before and after the delivery receipt is saved.
5. Check that there is one write and one audit row, and that the exact
result survives.

**Paperclip version or commit**

The change was developed from `44736c9c7` and rebased onto `0e5830887`.

**Deployment mode**

Self-hosted server with the native runner. Tests use local runner
processes, scripted providers, and PostgreSQL.

Related work: #12353 added durable semantic tool receipts; #12384 added
durable Codex tool recovery; #12404 bound semantic tools to ACPX
sessions. #14633 covers separate native-provider cancellation and
qualification work. This PR addresses server semantic-tool outcomes and
their durable delivery. No duplicate fix was found. AgentMail discovery
is outside this PR.

## What Changed

- Close turn admission without inventing results for dispatched tools.
Keep pending calls and accept late actual results.
- Accept identical result replay with a diagnostic warning. Include call
identity and both result hashes in real conflict errors.
- Preserve exact execution arguments. Reject prohibited or oversized
input before dispatch. Keep diagnostic previews redacted and bounded.
- Commit instruction-attempt evidence before the filesystem write. Save
completed mutation receipts so concurrent and restarted duplicates
return the first result. Recheck authorization before replay. An attempt
without a completed result stays unknown and cannot execute again.
Definite pre-write failures save and replay their original error without
another write.
- Recover an interrupted saved-result delivery only for backends with
durable result receipts. Never replay an ordinary business operation
with an unknown outcome.
- Preserve the initiating error when cleanup also fails. Record
incomplete settlement evidence. Propagate typed unknown-outcome errors
through the native tool wrapper without creating a false completed tool
result.
- Append run-log attempts and restore the durable log before appending
after local file loss. Reject incomplete restores. Publish a restored
prefix only if the destination is absent so concurrent attempts cannot
overwrite new lines.
- Add deterministic race, crash, replay, authorization, exact-content,
and log-restoration tests. Document their assertions in
`packages/paperclip-runner/docs/durable-recovery.md`.

## Verification

- Current head: `7e088f4c7fba8ebabf98ae95485a5753b013d489`. All 55
applicable checks pass; four conditional/manual checks are skipped. This
includes build, typecheck, Rust, both runner TypeScript shards, server
and workspace tests, all eight browser shards, isolated runner
compilation, and the clean-install release dry run. [CI
run](https://github.com/paperclipai/paperclip/actions/runs/36746101110).
- Greptile reviewed this exact head at 5/5 with zero new findings. All
three earlier review threads are resolved.
- Focused local verification includes 11 instruction integration tests,
23 surrounding authority/tool tests, 26 run-log tests, and 169
controller/driver tests. The post-rebase controller/transport/runtime
selection passed 415 tests. The full Rust release suite passed 617 tests
with two ignored. The real-process SIGKILL recovery test passed three
consecutive runs.
- The fault matrix in
`packages/paperclip-runner/docs/durable-recovery.md` uses explicit
barriers, real PostgreSQL rollback, durable journal reloads, and killed
runner processes. It covers late results, identical and conflicting
replay, exact long content, concurrent log restoration, lost commit
acknowledgements, and definite failure replay after the original CAS
base becomes valid again. No paid model calls are needed.
- Full local recursive typecheck and build passed during implementation.
Server typecheck and the runner TypeScript build passed after the review
fixes. The broad local repository test run was stopped after repeated
database startup timeouts. Four timing/launch failures in an earlier
broad runner run passed focused reruns without changed assertions or
timeouts. These are local verification limitations; the complete
current-head CI suite is green. An earlier CI workspace job received an
infrastructure shutdown signal; its current-head replacement passed.

## Risks

- A stopped turn can remain blocked when a dispatched operation has no
proven result. The system does not guess its outcome or rerun its
effect.
- Conflicting results still fail settlement. Existing failed or
conflicting journals are not repaired automatically.
- Accepted semantic input is limited to 480 KiB of encoded JSON to fit
the encrypted transport. Larger input fails before execution.
- Instruction filesystem writes and database receipts are not one atomic
storage operation. A separately committed attempt and audit record
survive rollback. An attempt without a completed success or definite
pre-write failure receipt remains blocked as an unknown outcome. It is
not replayed or reported as success.
- Run-log restoration now reads the durable object before appending when
the local log is missing. Failed or incomplete reads reject the append.
- No schema migration, dependency change, workflow change, or AgentMail
change is included.

## Model Used

OpenAI Codex, GPT-6, with reasoning, tool use, code execution, and test
analysis. The exact served model ID and context-window size are not
exposed in this session.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass (focused suites; the broad
local run limitation is recorded 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-09-30 11:54:56 -05:00
Nicky LeachandPaperclip af5c2d101c fix(paperclip-runner): deliver the shutdown settlement event past the terminal-turn gate (#14668)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - The OpenCode driver maps provider events to runtime request events
> - A provider turn can end before a pending runtime request receives
its answer
> - The consumer reads one turn's events and stops at that turn's
terminal event
> - A settlement event that arrives after that terminal event never
reaches the consumer
> - This pull request settles the request inside its own turn, before
the terminal event
> - The benefit is reliable request settlement without weakening
late-frame protection

## Linked Issues or Issue Description

**What happened?**

A pending runtime request stayed open after an OpenCode turn failed
through `session.error`. Session shutdown then dropped its settlement
event as a late provider frame.

**Expected behavior**

The driver must deliver `runtime_request.expired` with the original
`turnId` and `itemId`, inside the same single read pass the consumer
performs on that turn.

**Steps to reproduce**

1. Start an OpenCode turn that creates a native runtime request.
2. Leave the request pending and fail the turn through `session.error`.
3. Close the session and inspect the emitted events.

**Paperclip version or commit**

`22d41c6081f05658e0d7c8485d0f22f35af4a79e`

**Deployment mode**

Built from source with the OpenCode driver test fixture.

## What Changed

- Settle a pending runtime request as soon as its own turn goes
terminal, before the terminal turn event.
- Add an optional `bypassTerminalTurnGate` parameter to the OpenCode
session emitter, and set it on the settlement emit.
- Keep a settlement loop in session close as a fallback for a request
whose turn never went terminal.
- Add a fixture trigger and a regression test that reads one turn in a
single pass.
- Keep the late provider frame gate unchanged for every provider event
path.

## Verification

- Run `pnpm vitest run
packages/paperclip-runner/src/drivers/opencode/opencode-server-driver.test.ts`.
- Run `tsc -p tsconfig.json --noEmit` in `packages/paperclip-runner`.
- Run `tsc -p tsconfig.surfaces.json --noEmit` in
`packages/paperclip-runner`.
- Confirm that the regression test receives `runtime_request.expired`
with the original identifiers.
- Confirm that the late-frame tests still report dropped provider
frames.

## Risks

Four call sites now reach the settlement path: session close and the
three terminal turn paths (completed, cancelled, and failed). At the
three terminal turn paths the turn is still the active turn, so the gate
admits the settlement event with or without the parameter. Session close
is the only place where the parameter changes the result of the gate,
and only for a request whose turn already ended. Every provider event
path keeps the existing terminal-turn gate. The known driver test
failure is pre-existing and does not touch this change.

## Model Used

Claude Sonnet 5, with code execution and test assistance.

## 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 the changed tests locally; the known pre-existing
failure remains documented above
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation, or no documentation change
applies
- [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 have addressed all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-09-30 09:48:14 -07:00
Nicky LeachandPaperclip eb31b926a1 fix(runner): keep the OpenCode session event stream open across turns (#14582)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - Paperclip Runner keeps provider sessions and their event streams for
agent runs
> - The OpenCode driver closed its event queue after each terminal turn
> - A second turn on the same session then lost its response and
completion events
> - This pull request keeps the queue open between turns and rejects
late events for sealed turns
> - The benefit is reliable multi-turn OpenCode sessions with visible
diagnostics for late provider events

## Linked Issues or Issue Description

**What happened?**

The OpenCode driver closed its event queue when a turn completed, was
cancelled, or failed. A second turn on the same session then lost its
response and completion events.

**Expected behavior**

The session must keep its event stream open between turns. Each turn
must deliver its response and one terminal event. The session must close
the stream only during session shutdown or an unrecoverable pump error.

**Steps to reproduce**

1. Start one OpenCode session.
2. Run one turn and wait for its terminal event.
3. Run a second turn on the same session.
4. Confirm that the second turn delivers its response and terminal
event.

**Paperclip version or commit**

`c0e1d87ddc181329471fa80a2061b2c538bb6618`

**Deployment mode**

Built from source with the Paperclip Runner package test suite.

## What Changed

- Keep the OpenCode event queue open across completed, cancelled, and
failed turns.
- Track sealed turn ids and reject later events for those turns with a
diagnostic event.
- Preserve queue shutdown on session close and unrecoverable pump
errors.
- Give each simulated fixture turn unique provider event ids.
- Add regression tests for completed, cancelled, failed, and
closed-session paths.

## Verification

- Type check: `cd packages/paperclip-runner && node
./node_modules/typescript/bin/tsc -p tsconfig.json --noEmit` passed.
- Driver tests: `cd packages/paperclip-runner && npx vitest run
src/drivers/opencode/opencode-server-driver.test.ts` passed except for
the known pre-existing flaky test described below.
- Consumer tests: `cd packages/paperclip-runner && npx vitest run
src/native-session-runtime.test.ts
src/backends/harness-driver-backend.test.ts
src/cli/opencode-app-server-proxy.test.ts
src/conformance/harness-driver.test.ts` passed.
- The known flaky test reproduced on unmodified `master` because fixture
event order depends on a local MCP HTTP round-trip.
- CI must run the full pull request suite.

## Risks

- The queue now retains sealed turn ids for the session lifetime.
OpenCode does not reuse turn ids, so this set grows with the session.
- A late provider event cannot reach a later turn. The driver emits a
diagnostic event so the rejection remains visible.
- The change does not alter session shutdown or unrecoverable pump error
handling.

> For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and
discuss it in `#dev` before opening the PR. This pull request fixes an
OpenCode Runner bug and does not add a roadmap feature.

## Model Used

OpenAI Codex, GPT-5, tool use and code execution; Anthropic Claude
Sonnet 5 also assisted with the implementation. The runtime did not
provide a 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-09-29 22:05:41 -07:00
da887ea3e9 fix(runner): honor Codex effort selected in composer (#14568)
## Thinking Path

> - Paperclip manages AI agents that work on assigned tasks.
> - The task composer lets a person choose an assignee, model, and
effort for the next run.
> - A Paperclip Runner agent can use Codex as its provider.
> - The composer hid Codex effort for that agent because it checked only
the older Codex adapter.
> - The native Runner input also did not carry an effort choice to
Codex.
> - This pull request carries the chosen effort from the composer to
each Codex turn.
> - People can now select a supported effort and get the effort they
selected.

## Linked Issues or Issue Description

Refs #14322

**What happened?**

The composer showed a model but no effort slider when the assignee used
Paperclip Runner with the Codex provider. A task-level model override
also did not reach the native Runner input.

**Expected behavior**

The composer shows effort choices for a known Codex model. The next
native Codex turn uses the selected model and effort.

**Steps to reproduce**

1. Open a task composer.
2. Select an agent that uses Paperclip Runner with the Codex provider.
3. Select a known Codex model such as `gpt-6-astra`.
4. Open the assignee and model picker. The effort slider is missing
before this change.

## What Changed

- Show known Codex effort levels for Paperclip Runner Codex assignees.
- Save the task effort override in the native run input and send it to
Codex on each turn.
- Apply the task's merged model and effort overrides when the native run
starts.
- Apply a task model override for OpenCode Runner without changing the
agent's provider.
- Add Runner effort tests and desktop and mobile Storybook cases.

## Verification

- `pnpm -r typecheck` passed.
- `pnpm build` passed.
- `pnpm build-storybook` passed.
- `pnpm check:token-gates` passed.
- Focused UI, server, Runner contract, and Codex driver tests passed.
- The full CI test matrix, build, typecheck, and canary dry run passed
on the latest head.

## Risks

- Native Runner inputs add an optional Codex effort field to the current
v5 input. Older inputs keep their previous behavior.
- A known model rejects an effort that its catalog does not support.
Unknown models do not show a slider.

> This fixes an existing composer bug. I checked `ROADMAP.md`; it does
not describe this bug as planned work.

## Model Used

OpenAI Codex, GPT-6. The exact deployment ID and context window are not
exposed in this session. The model used reasoning, 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)
- [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>
Co-authored-by: OpenAI GPT-6 Astra <noreply@openai.com>
2026-09-29 09:41:05 -05:00
DottaandPaperclip 24beb00575 feat(runner): add rich ACP transport and durable interaction foundation (#14430)
Add shared rich ACP transport, durable questions and permissions, verified provider packaging, and bounded activity and plan presentation. Keep Cursor, Copilot, and Pi pending their separate provider qualification.

Persist interaction settlement before publication, fence failed writes until fresh recovery, and preserve owned-process cleanup. Incorporate reviewed mainline integration with extended harness coverage.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-09-29 08:56:21 -05:00
DottaandFry 3ca196b0a6 feat(agents): persist agent files across tasks without revision history (#14420)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - An agent needs personal files across tasks and sessions.
> - AGENTS.md is one file in that directory. Supporting files need the
same persistence.
> - The Instructions Editor and agent runs must share one current
directory.
> - Concurrent runs should apply only the files they change. The last
sync of the same file wins.
> - This pull request uses existing file transport and removes temporary
copies after sync.
> - Old instruction-only sessions keep their restore contract. New saves
do not create revision history.

## Linked Issues or Issue Description

Refs #14325. This replaces its revision-oriented design with persistent
agent files. Keep #14325 unmerged.

Transport prerequisite #14416 merged first at
`d172197117a14b80a1eb2d2835a0e7cce2679656`. This PR now targets master
and remains below 100 changed files.

Related work: #4513 and #8798 cover instruction tooling. This change
handles run synchronization, cross-task personal files, browser editing,
and old-session restoration.

## What Changed

- Keep one current directory per company and agent. Point AGENT_HOME at
a temporary working copy for each active run. Keep task files and
provider HOME separate.
- Restore text, binary files, and nested folders through workspace
transport. Exclude remote agent files from task Git snapshots with a
self-ignoring file inside the reserved runtime directory; never write
through repository-controlled Git metadata.
- Collect after the provider and child processes have stopped. Keep
resumable conversation state.
- Apply changed and deleted files under the agent lock. The last sync
wins for the same file. Unrelated concurrent changes survive.
- Remove temporary copies after successful sync, rejected sync, and
staging failure. Register ownership before copying so restart recovery
can remove interrupted preparation. Retry transient synchronization up
to three times. Preserve the original remote lease reference until
deletion succeeds; restart cleanup never acquires a replacement sandbox.
Do not create captured directories or a conflict-review queue for new
runs.
- Keep browser editing, stale-draft protection, and streaming binary
downloads. Keep the instruction entry and text editor limited to 1 MiB.
- Keep historical agent-folder sync failures on their affected runs
instead of repeating them above current saved instructions. Preserve
legacy candidate review and current browser-save errors. Avoid duplicate
quota warnings while retaining separate sync failures when they describe
a different problem.
- Require target-scoped caller grants for peer instruction access, while
preserving self edits, responsible-user checks, and protected-change
consent.
- Treat full storage as a nonblocking run warning, never an agent pause
or run-admission failure. Restore already-over-quota saved folders so
ordinary agent cleanup can recover; warn on each run until cleanup. The
run detail view shows the warning.
- Allow 256 MiB per file, 2 GiB per directory, and 100,000 entries. Hash
large files as streams. Check editor-save quotas with metadata instead
of hashing unrelated files.
- Preserve old native inputs, instruction-only copies, paths, digests,
and pending legacy candidates. Adopt old revision heads once. New writes
do not append history rows.
- Add idempotent migration 0287 and verify upgrades from the preview
tables and receipts.
- Add nine interactive stories under **Agents / Persistent files**,
including automatic incoming edits, stale browser drafts, and
storage-limit diagnostics.

## Verification

- Merge candidate: `4f5390107ec6ffd80a76d1d2e85530e66f21d079`, after
merging current master and the landed transport prerequisite.
Integration required no manual conflict resolution; the feature remains
99 changed files. Full workspace typecheck, production build, token
gates, and 715 focused tests passed on this merge candidate. Fresh
Greptile review is 5/5 with no unresolved findings. All 55 checks
passed, with four conditional skips, including the build, typecheck,
browser E2E, and canary dry run. A single retry recovered four jobs
interrupted by runner shutdowns; no source changes were required.
- Historical-warning UI fix: all 6,834 UI tests across 640 files passed,
including regression coverage for three old failures, legacy preserved
edits, and warnings scoped to the affected run. Full workspace
typecheck, production build, Storybook build, and token gates passed.
Browser-verified Storybook playtests passed for Historical Failures
After Successful Save, Storage Limit, and Full Storage Run Warning.
- Review follow-ups at `4e20c9fb2`: all 18 focused tests passed,
including external Git directories, linked worktrees, symlinks,
hardlinks, and distinct I/O failures alongside storage warnings. Server
and UI typechecks, token gates, and the production build passed.
- Storage warning regressions at `0724f3012`: all 33 directory tests and
all five heartbeat-list tests passed, with no skips in their successful
runs. They cover repeated runs while full, an already-over-quota saved
folder, cleanup, warnings retained after unrelated save failures, and
bounded warnings in large result JSON. Server typecheck passed after the
final warning fixes.
- Full workspace typecheck, production build, and token gates passed
during this follow-up. Product E2E harness: 631 tests passed across 52
files; harness typecheck passed. Earlier native session/context and
directory/legacy collection suites passed 537 tests; Runner
unit/transport suites passed 329 tests.
- **Real E2E at `0724f3012` (before this follow-up):** legacy local
Codex and native Daytona Codex each passed six tasks, one server
restart, seven independent assertions, and cleanup verification. Both
prove browser-to-agent edits, agent-to-browser edits, nested/binary
restoration, per-file last-sync-wins, a successful run after an
oversized save rejection, and cleanup clearing the warning.
- Native local Codex also passed the six-task quota flow before the
final warning-retention fixes. That pass began at `918d1ed02` while the
bounded-result warning fix was being edited, so it is not claimed as
exact-final-head evidence. Its final-head rerun failed during embedded
PostgreSQL bootstrap before any provider run: the macOS host had 87,365
of 87,381 SysV semaphores occupied. No unrelated services or kernel
limits were changed.
- The final-source report intentionally records **2/3 cells passed**,
preserving the blocked native-local attempt:
`tests/runner-e2e/results/agent-files-quota-final-20260928-report/`.
Earlier failed attempts and provenance notes remain under
`tests/runner-e2e/results/agent-files-quota-final-20260928-input/` and
the original campaign directories.
- Daytona used immutable image
`ghcr.io/paperclipai/paperclip-daytona-runner@sha256:5643f0d801417cae3581833a1a3bc6715b325e028602738d2652c44cac5dc6bf`
and its exact Linux runner binary. Controller source is `0724f3012`;
image source is recorded separately.
- Legacy-session compatibility and all three ACP Stop/resume browser
regressions passed on the prior validated feature head
`169fab46d5af21caa2269b4c1b29b69c933a6951`. They assert the same
provider session is retained and interrupted writes are not replayed.
Migration upgrade tests also passed earlier.
- Nine interactive stories are under **Agents / Persistent files**,
including **Full Storage Run Warning**. Its playtest and visual browser
inspection passed; the warning states that runs continue and the editor
remains available.
- Prior-head checks on `4e20c9fb2`: 55 passed, two conditional jobs
skipped, no failures or pending checks. All eight browser E2E shards and
their aggregate passed. Fresh Greptile review is 5/5 with no findings;
all review threads are resolved, the security scan passed, and GitHub
reports no merge conflicts.
- The broad local follow-up test run was interrupted after host
semaphore exhaustion affected isolated PostgreSQL instances. It also
encountered the existing macOS long-path fixture failure and two timeout
failures. This is not a claim that the full local suite passed. Logs are
retained; focused storage/warning tests passed.

## Risks

- A later sync can overwrite an earlier edit to the same file, including
a saved browser edit. There is no text merge or retained version. This
is the intended last-sync-wins policy.
- A save that exceeds a storage limit is rejected and its temporary copy
is discarded. The run itself continues normally, and later runs restore
the last saved files with a warning until cleanup. Transient sync
failures get bounded retries. An I/O failure partway through a sync can
leave some files updated; a failed receipt does not claim whole-folder
success.
- Larger folders increase copy time, network traffic, and temporary disk
usage. Active runs still need working copies. Terminal runs do not
accumulate archives. Operators must provision disk for agents and
configured concurrency; these limits are not company-wide quotas.
- A restored old native session remains instruction-only until a fresh
session starts. Its original conflict fence and existing pending
candidates remain compatible.
- Provider processes close at the collection boundary. Conversation
resume remains available, but warm process reuse is lost.
- Backups must include the instance filesystem and database. External
bundles keep their existing behavior until explicitly moved to managed
storage.

## Model Used

OpenAI Codex, GPT-6 family. The session does not expose a more specific
model ID or context-window size. Reasoning, code execution, and browser
tools assisted this change. Real provider E2E uses `gpt-5.6-sol`.

## 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: Fry (Paperclip) <noreply@paperclip.ing>
2026-09-29 08:25:56 -05:00
DottaandPaperclip 18e8c121d9 fix(runner): include Grok support in public installs with sandbox prerequisites (#14024)
## Thinking Path

> - Paperclip manages agents through a shared native runner.
> - Built-in harness support should ship with Paperclip's public
distribution.
> - Grok already speaks ACP; it does not require a new public bridge
package.
> - Sandbox provisioning owns the native executable and its pinned
version.
> - The runner must verify that prerequisite without downloading it
during npm installation.
> - This change separates built-in launcher identity from external
runtime identity.
> - Clean npm installation and live staging checks verify the
distribution boundary.

## Linked Issues or Issue Description

Refs #13882, #13973, #13977, #13979.

This follow-up now targets master after #13882 was squash-merged. It
replaces the private `@paperclipai/grok-acp` workspace package with
runner-owned assets. Current master is included so the branch also
contains the merged scheduler, complete-event capture, and durable
cleanup fixes.

## What Changed

- Ship Grok launcher and qualification metadata inside the runner's
compiled output and the public server's vendored runner tree.
- Remove the separate Grok npm package and all package-manager install
hooks for this runtime.
- Require the checksum-verified Grok Build 1.0.13 binary at
`/opt/paperclip/providers/grok/1.0.13/grok` in the selected execution
environment. Provision it explicitly in the Daytona image and CI setup.
- Keep native binaries outside the provider pack. Bind the built-in
launcher into the pack manifest.
- Preserve executable leases, descriptor-backed startup, credential
fences, permissions, and exact ACP model admission.
- Use `builtin:grok-acp` and `native:grok` as profile identities.
Historical package-profile sessions fail closed on resume rather than
being silently reinterpreted.
- Resolve built-in assets from the authenticated sidecar location,
including public server npm layouts. Keep the controller path out of
provider environments.
- Add clean npm tarball installation verification to the existing
trusted canary CI job and the admitted manual EC2 verification path. It
stages a unified release version and runs npm lifecycle scripts, then
verifies missing-prerequisite rejection and admission after separate
provisioning without credentials or inference.
- Include the controller-owned provider pack in stamped Cloud images.
Unstamped local images omit the pack and remain usable; remote ACPX
requires full source provenance.
- Correct CLI approval-page metadata for an already authenticated Cloud
board user; approval authorization remains unchanged.
- Honor explicit native-runner enablement in the Cloud agent picker and
direct setup page, keeping the flag disabled by default.
- Allow selecting the execution environment before connecting
credentials. Include Grok in the existing authenticated hello-probe
flow, targeting its pinned native prerequisite for runner setup.
- Recover an existing subscription sign-in conflict through an explicit
cancel-and-retry action, serialized after cancellation succeeds.
- Preserve the selected ACPX harness before normalizing config fields,
so new Grok agents use the Grok default model.
- Keep the credential-free Cloud provider pack root-owned and readable
after runtime UID remapping; verify manifest and referenced asset access
under an unrelated unprivileged UID during image builds.
- Archive prior failover backups alongside explicitly replaced harness
state, preserving evidence while preventing stale backups from blocking
a fresh replacement.
- Update Daytona image content inputs and contract tests for the
built-in assets and explicit provisioner.
- Document and regression-test the shared `approve-all` default for Grok
setup, saved configuration, and native execution. Explicitly saved
restrictions remain unchanged.

## Verification

Current merge-repair head `df09eb3e1a619430ad8419a0ee9aedd486689b05`
incorporates master `f1a394bd30cb56fb9e479f98b9f50176fe921858` after the
base PR was squash-merged. All 12 conflicts came from incoming files
identical to the tested pre-squash base. The final tree exactly matches
a three-way merge using that original base, preserving built-in Grok
distribution and removal of the obsolete private package. All 252
focused runner/UI tests, six npm-isolation tests, and token gates pass.
Fresh exact-head Greptile review is 5/5 with no outstanding findings;
security scans and EC2 native compilation pass. All current-head CI is
green: 56 successful checks/statuses and four intentional skips ([run
36468768035](https://github.com/paperclipai/paperclip/actions/runs/36468768035)).
The repository owner explicitly authorized bypassing code-owner approval
after all checks passed; no CI checks or repository protection settings
are bypassed or changed. The only remaining PR was removed from the
completed stack metadata to permit native auto-merge.

Earlier integration head `78cb306ecc41b5c96577c26c1d89153b0ef865a1`
includes master `3447609d2247e75e55d91493dda91a608364f672` (2026-09-28).
Two master advances during verification overlapped the eval catalog; the
final merge preserves Grok qualification, completion updates, and
bounded API-response reading in all 348 cells. All 77 focused
catalog/eval/workflow tests pass. Both native stack layers (#14397) are
mergeable, and both exact-head Greptile reviews are 5/5 with successful
security scans and no unresolved review threads. All current-head CI is
green: 56 successful checks/statuses and four intentional skips ([CI
attempts](https://github.com/paperclipai/paperclip/actions/runs/36447124691)).
The initial attempt lost two EC2 runners to shutdown signals and stalled
a third shard during dependency preparation; all three passed the
same-commit failed-job-only retry. Trunk code-owner requirements remain
enforced. The review summary’s non-blocking saved-asset offset
classification note concerns code already merged in #14301; those
runtime files are identical to master and outside this stack’s diff.
Historical live evidence below retains its original source revisions.
[Final public npm
verification](https://github.com/paperclipai/paperclip/actions/runs/36445542764)
passed on `76ea70cd4d13786a042af9df82f0fd7a8c85ae30`: 17 public
packages, an executed offline lifecycle sentinel, unchanged consumer
lock, built-in launcher, missing-prerequisite rejection, and verified
separately provisioned binary/command lease. Provisioning and cleanup
require no host privilege elevation; only the positive probe mounts the
temporary native binary read-only. The verifier is unchanged by the
final master merge. All six isolation tests and an offline npm smoke
test pass. The prior head had 56 green CI checks and a 5/5 review after
two unchanged tests timed out and passed a failed-job-only retry ([CI
attempts](https://github.com/paperclipai/paperclip/actions/runs/36444597313)).
All 56 recovery-display/lineage tests pass; re-review cleared the
already-covered missed-retry concern. Earlier EC2 failures remain
retained: [npm lockfile
rejection](https://github.com/paperclipai/paperclip/actions/runs/36436311203),
[missing compiler in the slim
image](https://github.com/paperclipai/paperclip/actions/runs/36440210984),
and the aggregate 15-minute test timeouts in those broad runs. Both
broad attempts passed typecheck, token gates, Product E2E type/unit
checks and build. The focused EC2 lane preserves the existing
trusted-actor and immutable-source gates.


Earlier documentation/test checkpoint
`ff244c4fd78a7ede5a3e00efe09f475f133ef33e` leaves runtime behavior
unchanged. 154 focused tests pass across configuration building, native
provider resolution, permission policy, credentials, UI configuration,
and new-agent setup (including both Grok auth modes); token gates pass.
All fresh CI is green for this head: 56 successful checks/statuses and
two intentional skips ([run
36367065119](https://github.com/paperclipai/paperclip/actions/runs/36367065119)).
Greptile is 5/5 with no new findings. Grok already inherits the shared
`approve-all` default, so unattended setup requires no manual permission
change.

Runtime head `bb5a9307991f1ac567b781970ef11b39d518e19b` fixes a final
staging continuation failure before provider startup: explicit
replacement archived the old harness but left its failover backups
active, which caused `runner_harness_state_mismatch`. The regression
fails before the fix and passes after it; all eight adjacent
recovery-safety cases also pass. Old backups remain inspectable inside
the continuity archive. All fresh CI is green at this head ([run
36360839248](https://github.com/paperclipai/paperclip/actions/runs/36360839248)),
with a 5/5 review. One unrelated Cursor test timed out in the initial
server shard; the same-commit failed-job rerun passed, and both attempts
are retained. Staging deployment is confirmed healthy on this revision.
The controller image is
`ghcr.io/paperclipai/paperclip@sha256:6ad91c487910ccd2596ff7aed0a3a3ea5233d12b51b83cd6e1402237749b9673`.
The final browser-created staging task passed on this exact revision
with API authentication: context read → structured human question →
controller restart → answer submission → same native provider session
resumed → document saved → task Done. The two turns took approximately
119s and 77s. The actual write receipt was applied, and the saved
document has exactly one revision containing the selected answer and
requested marker. Usage and cost were not reported. [Controller image
build](https://github.com/paperclipai/paperclip/actions/runs/36360889243).

- Previous integration head `a44f7dbb6b6f77cd9ed893756ca453307f281e5f`:
all CI green (53 successful checks/statuses, two intentional skips),
including repository typecheck/build/tests, native Runner tests, browser
shards, and canary installation checks. [CI run
36358672529](https://github.com/paperclipai/paperclip/actions/runs/36358672529).
Greptile is 5/5 with no unresolved findings.
- Focused checks cover Grok credentials, executable admission, launcher
assets, provider-pack paths/permissions, workflow contracts, setup
defaults, CLI authorization, and subscription conflict recovery. All 39
protocol definitions validate. Final integration checks pass 124
catalog/evidence/cache tests and nine project-form tests; token gates
pass. Some local dependency checks could not load the stale installed
dependency tree; the corresponding fresh EC2 checks pass.
- Clean public npm installation passed on EC2 at
`8b172ebcf8e02e30662d830c00f3961e3bd459ec` ([run
36164964900](https://github.com/paperclipai/paperclip/actions/runs/36164964900)):
17 unified-version packages, lifecycle scripts enabled, built-in
launcher present, no separate Grok package or npm-downloaded binary,
missing prerequisite rejected, separately provisioned native executable
and command lease verified. No credentials or inference were used.
Subsequent changes preserve this npm asset layout.
- The immutable Daytona prerequisite image is
`ghcr.io/paperclipai/paperclip-daytona-runner@sha256:98957d5be0ac774d086b6402b5849e8e6356fec70fb8c09fca6eb4ed6de918e0`,
built from `5a2db471f3ddabe77f9f80e76ed27f996cb97fba`. The previous
Cloud controller image was
`ghcr.io/paperclipai/paperclip@sha256:fd914e1ab1e45f741e8e078ff452d16f082d7ac05f9b4b3506d3a3c64150d204`,
built from `a44f7dbb6b6f77cd9ed893756ca453307f281e5f`; it is superseded
by the latest image above. Its EC2 build verified provider-pack access
under an unrelated unprivileged UID.
- Browser staging at `40f898bc4cba73c1dff4e6344a3983ba0fb247ef` passed
full Grok onboarding with the correct `grok-4.7` model, saved credential
delivery, and pinned Daytona execution. A browser-created task read
context and asked the structured human question. After a controller
restart, answering the persisted question resumed the same native
provider session, saved the requested document, and completed the task.
Actual tool outcomes and durable state agree: one question and one
document revision. The two successful turns took 42.7s and 63.1s; usage
and cost were not reported.
- Restricted policy returned the expected `approval_required` outcome.
Functional staging tests explicitly selected `approve-all`; controller
authorization and governed approvals remain enforced. Temporary board
CLI access was revoked and verified rejected (HTTP 401), and the
disposable onboarding agent was paused.

Failures remain retained: the pre-fix continuation failure (its task
remains blocked; the passing final task is fresh), the original Cloud
provider-pack permission failure, the expected restricted-policy denial,
the superseded npm staging failure, and an earlier monolithic CI
infrastructure timeout. Browser CI exposed a project alias/form race;
the final stack uses master's stronger draft-preservation fix and all
browser shards pass. Historical full subscription/API protocol and
Product rosters retain their original source revisions and do not
qualify this packaging revision. No local Docker or Rust build was used.

## Risks

The branch includes master’s draft-preservation fix for project URL
aliases. It keeps the same project’s edit form mounted and clears prior
data when the project or company changes.

Custom sandboxes and local execution hosts must provision the pinned
binary before Grok starts. Missing, changed, unsupported-platform, and
symlinked executables fail admission. The new builtin profile cannot
resume sessions created with the former private-package profile.
Existing Claude/Codex npm bridge profiles retain their package pins.
Grok restricted modes preserve the selected policy but cannot
automatically admit Paperclip calls: ACP permission metadata does not
independently bind tool authority, so those calls stop with
`approval_required`. New Grok configurations default to `approve-all`,
including API configurations that omit the mode. Existing explicitly
restricted configurations remain restricted; controller authorization
and governed approvals remain enforced.

## Model Used

OpenAI GPT-6 through Codex, with tool use and code execution. The exact
serving model identifier 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-09-28 14:54:44 -05:00
DottaandPaperclip 992f720262 fix: make runner task context ownership explicit (#13753)
<!-- Write all pull request text in Simplified Technical English
(ASD-STE100). -->

## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Task descriptions, comments, continuation data, skills, and
execution rules enter several agent adapters.
> - The same source can be rendered by more than one automatic input
carrier.
> - Failed resumes can also rebuild input from stale or compact context.
> - This pull request gives each Paperclip-owned source one delivery
owner and preserves the required transport boundaries.
> - It adds deterministic adapter, interaction, runner, and browser
tests for these boundaries.
> - The benefit is more predictable context delivery with explicit
evidence for later live qualification.

## Linked Issues or Issue Description

Related: #13144 removes a duplicate environment payload and bounds wake
lists. Related: #11360 addresses Hermes resume behavior. This pull
request preserves compatible active-session formats while repairing
context ownership and stale question creation.

**What happened?**

Task descriptions and comments could enter more than one automatic
context block. Native transports could wrap a complete model input in a
second task envelope. Some legacy and gateway adapters could omit the
owned assignment on ordinary tasks or rebuild a failed resume with stale
compact context. A continuation could also request a question after
newer human comments had arrived.

**Expected behavior**

Each task or comment source has one automatic model-facing owner.
Distinct comment IDs and repeated wording remain distinct. Fresh
fallback attempts rebuild the required full context. A question request
is rejected when newer queued human direction makes it stale. Harness
access policy remains owned by execution configuration.

**Steps to reproduce**

1. Build a task with a description and current comments.
2. Capture the actual adapter or runner input.
3. Compare source ownership and task-envelope nesting.
4. Queue a human comment before a continuation requests a question.
5. Trigger a failed resume and inspect the fresh retry input.
6. Run the focused adapter, interaction, runner, and browser checks.

## What Changed

- Add shared prompt-section selection at the provider-attempt boundary.
- Deliver owned assignment context through native, legacy CLI, ACP,
gateway, cloud, Pi, Kimi, Grok, Gemini, OpenCode, Cursor, OpenClaw, and
Hermes paths.
- Rebuild full or compact context after resume recovery changes the
attempt. Add native and Claude ACP tests of actual recovery requests.
- Preserve custom templates, loaded instruction files, execution
policies, and older active-session formats.
- Record continuation source metadata and reject stale question creation
under the issue-row lock.
- Add explicit Product E2E context-integrity profiles, prerequisite
gates, credential-isolation checks, and report fixtures.
- Bypass service-worker forwarding for same-origin Vite development
modules. A real Chromium test fails with resource exhaustion before the
repair and passes after it. Production asset caching keeps its existing
policy.
- Add browser diagnostics and service-worker module-loading regressions.
- Add an explicit zero-retry eval option. The default retry behavior
remains unchanged. Each campaign records its effective policy.
- Remove the model-facing working-directory sentence from four prompt
builders. Existing workspace, sandbox, permission, and custom-template
configuration remains unchanged.
- Align the everyday workflow assertion with the current 47-entry
catalog.

Compared with current upstream master, the branch carries the
context-ownership implementation and its tests, the explicit
context-integrity catalog and evidence harness, and the focused browser
regression checks.

## Verification

**Merge assessment:** focused regression evidence supports merge. This
is not full completion of the original broad qualification matrix. The
maintainer has authorized merge after fresh verification of the master
integration.

- Current head: `bbd52f82114eabf09bc7b1a7e97d54a5b43bbc00`. This
integrates current master `2f585ef26a1814fa209715242d1ca791b63e4c4e`.
All 14 conflicts are resolved. Cancellation checks, workspace
finalization, native Grok support, and both sets of tests are retained.
- Current-head Greptile: **5/5**, with no blocking findings. The review
names this exact commit. All **59 reported checks are terminal: 55
successful, 4 skipped, zero pending or failing**. This includes the full
root general and serialized suites, separate runner checks, typecheck,
build, canary, browser E2E, Docker, and security checks. The successful
legacy security status is included in that total.
- After integration: workspace typecheck and full build passed. Separate
runner checks passed: **2,160 TypeScript tests (10 skipped), 582 Rust
tests, and 39 preparation checks**. Other passing checks include 621
Product E2E harness units, 376 focused shared/adapter tests, 160
real-database/API tests, 86 Hermes tests, 18 browser-support checks, and
Product E2E typechecking. The complete root suite passed in CI. The
duplicate local monolithic root run was stopped after that CI result; it
is not counted as a completed local pass.
- New native recovery coverage retains full assignment, completion
contract, and explicit skill selection after safe replacement, for old
and prepared input formats. Full native session test file: **136/136
passed**.
- New Claude ACP coverage captures actual fresh, resumed, and
missing-session fallback requests. It verifies one assignment copy,
comment order, identical text under distinct comment IDs, and full
fallback context. Full file: **33/33 passed**. Both affected TypeScript
checks passed.
- Existing deterministic tests cover source revisions, approval and
trust boundaries, completion validation, custom templates, compatible
sessions, standalone driver wrapping, and maintained adapter transport
requests.
- Provider-free browser support: **17/17 passed** after the master
merge. Service-worker unit tests: **33/33 passed**. The module-overload
regression failed before the repair and passed after it in real
Chromium.

### Fresh live comparisons

The new batch ran exactly four Product E2E attempts. **All four passed
on the first attempt; no retries.** Each has six terminal matchers plus
the existing browser lifecycle and invariant checks.

| Exact case ID | Control | Candidate |
|---|---|---|
| `core-compatibility.runner-codex.local.plan-revise-accept` | Passed |
Passed |
|
`local-session-integrity.runner-acpx-claude.local.structured-question-restart-resume`
| Passed | Passed |

The plan case checks a revised canonical plan and revision-bound
approval before completion. The question case restarts the server before
submitting the answer, then verifies the continuation completes.

Control source is `dfa4e1bda8d50a1a01746603251a9128dbe9d0d6`. Candidate
source is `79fcdb5dece501d28064ea9da306603881b46f0c`. They use identical
frozen definitions and provider versions: Codex `0.156.0` with
`gpt-5.6-sol`; ACPX `0.13.1` / Claude ACP `0.73.0` with
`claude-sonnet-5`. The September 24 head added master browser recovery
and test-only changes. The September 28 head also integrates newer
master changes, including cancellation, workspace finalization, and
native Grok. These are frozen-source live results, not exact-head live
runs.

The candidate received one description copy where the control initially
received three. The submitted initial plan envelopes were 7,969 versus
19,097 characters. Question envelopes were 7,592 versus 18,919. These
are structural measurements, not whole-provider token or dollar savings.

### Earlier evidence and failed attempts

- The preceding fresh batch has four effective passing pairs: OpenCode
comment continuation and assigned skill, native Codex comment
continuation, and native Claude comment continuation. It retains **11
attempts: eight passed and three failed**.
- Original failures remain recorded: missing local PostgreSQL library
links before task creation; host-sleep cleanup after task/page checks
passed; and a Claude **control** session-open rejection before a model
turn. Setup was repaired identically on both worktrees. The permitted
unchanged infrastructure retries passed. The underlying Claude provider
startup error was not retained and remains unknown.
- Older R2 retains **17 passes and one failure** across 18 attempts,
including eight both-pass native/legacy Codex/Claude pairs. Its OpenCode
blank-page failure led to the service-worker repair. R2 is historical
evidence: master changed the native fixed prompt and removed duplicate
wake environment data afterward.
- The September 24 CI run initially failed one unrelated preview
readiness test (`ECONNREFUSED` on its local fixture). Its test and
production code match master. Isolated local verification passed **28
tests, 3 skipped**. One unchanged CI retry passed the full shard: **831
passed, 1 skipped**, including all **31 preview-exposure tests**. The
aggregate CI gate passed afterward. The precise startup cause remains
unknown; a port race is a hypothesis, not a proved cause.

### Limits

The original wider profile/workflow matrix, repeated trials, and remote
Daytona qualification are incomplete. These results support a focused
merge recommendation, not statistical equivalence or universal harness
qualification. Some usage receipts are missing in both variants, so no
token or dollar savings are claimed. The $500 ceiling was preserved
using conservative allowances; failed attempts and unknown charges
remain in the ledger.

Reproduce the focused additions with `pnpm exec vitest run
packages/adapters/claude-local/src/server/acp.test.ts` and `pnpm
--filter @paperclipai/paperclip-runner exec vitest run
src/native-session-runtime.test.ts`. Full checks use `pnpm -r
typecheck`, `pnpm test:run`, `pnpm build`, and the separate runner
checks. Paid evals require the frozen definitions, profiles, and
credentials; do not use `--all` as a substitute for the selected cases.

## Risks

- Context placement changes can affect model behavior. Deterministic
checks cover the selected paths, but live qualification remains
incomplete.
- The stale-question guard can reject a request when queued human
comments arrived during the run. This is intended.
- New stored inputs and model envelopes retain compatibility readers for
older active sessions.
- Custom templates may intentionally repeat content.
- Removing a model-facing working-directory sentence does not change
filesystem, command, sandbox, or permission configuration.
- The worker bypass applies only to same-origin development module
paths. Cache-policy tests preserve private-response handling and
production asset caching. Mounted HTTP fixture changes remain test-only.
- This PR does not claim measured token savings or statistical
equivalence across every harness.

## Model Used

OpenAI Codex, exact model gpt-6-astra, with repository tools and code
execution. Bounded supporting work used gpt-5.6-luna and gpt-6-luna. The
serving context-window size is not exposed in this task.

## 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 described the issue in-PR using the required issue fields
- [x] I have not referenced internal/instance-local Paperclip issues or
links
- [x] My branch name describes the change and contains no internal
ticket id
- [x] I have run the focused local checks and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect these changes
- [x] I have considered and documented risks above
- [x] All current-head Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
for the current head
- [x] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-09-28 14:49:14 -05:00
DottaandPaperclip f1a394bd30 feat(runner): add Grok Build through native ACP (#13882)
## Thinking Path

> - Paperclip manages AI agents and governs their work.
> - Its native runner uses structured provider protocols for sessions
and tools.
> - Grok Build supports ACP over stdio, but the runner did not expose
it.
> - Native execution requires company-scoped credentials, verified
identities, and permission gates.
> - This change adds Grok through ACPX for local and Daytona execution.
> - Subscription login and explicit API-key execution have separate
credential paths.
> - Qualification grades real tool outcomes, durable state, and browser
workflows.

## Linked Issues or Issue Description

Refs #13845, #13847, #13850, #13878, #13901, #13973, #13977, #13979.

Add **Grok Build** to `paperclip_runner` with `provider: "acpx"`,
`acpxAgent: "grok"`, and model `grok-4.7`. Existing legacy Grok agents
keep their adapter. Merge the three companion fixes (#13973, #13977,
#13979) before treating the integrated Product qualification as deployed
behavior.

## What Changed

- Synchronize shared, TypeScript, Rust, server, validation, and UI
provider contracts.
- Run Grok native ACP stdio through ACPX and the authenticated Paperclip
MCP bridge. Verify the pinned executable and exact ACP model identity.
- Prefer company subscription login. Support an explicit company-secret
API key without automatic paid fallback. Fence refresh and copyback to
the same account and remove private runtime credentials after
containment.
- Preserve selected permissions, cancellation, durable session identity,
resume, and restart recovery. Keep unsupported steering and goals
unavailable. Preserve missing usage and cost as unknown.
- Package checksum-verified Grok Build 1.0.13 for Daytona with an
immutable, signed image built on EC2.
- Add deterministic admission, protocol, permissions, identity,
credential, failure, and cleanup checks. Add the maintained 39-case
protocol roster and separate subscription/API Product profiles.
- Fix live-test findings in reasoning events, reloads, idle-owner
retirement, credential-home cleanup, expired-login model discovery,
launcher pinning, and rerun evidence selection.
- Align control-plane state readers with the transport's 64 MiB bound
while retaining identity, ownership, lifecycle, and size rejection
checks.
- Stabilize two asynchronous CI assertions while retaining actual
outcome and filesystem-evidence checks.

## Verification

Current integration head `f114948376056fe0b6b34c1496ae8667b59daa63`
includes master `3447609d2247e75e55d91493dda91a608364f672` (2026-09-28).
Two master advances during verification overlapped the eval catalog; the
final merge preserves Grok qualification, completion updates, and
bounded API-response reading in all 348 cells. All 77 focused
catalog/eval/workflow tests pass. Both native stack layers (#14397) are
mergeable, and both exact-head Greptile reviews are 5/5 with successful
security scans and no unresolved review threads. All current-head CI is
green: 56 successful checks/statuses and four intentional skips ([CI
run](https://github.com/paperclipai/paperclip/actions/runs/36447097232)).
Trunk code-owner requirements remain enforced. The review summary’s
non-blocking saved-asset offset classification note concerns code
already merged in #14301; those runtime files are identical to master
and outside this stack’s diff. Historical live evidence below retains
its original source revisions.


Earlier integration checkpoint:
`24fc9b94ca0afb21ccdc8d26dbb2e4b258ad72cb`. Refreshed against master
`0f14d2612`, preserving Grok qualification alongside the new accounting
and lifecycle suites. All 124 focused catalog, evidence, and
service-worker checks pass. The current base workflow includes the
explicitly selected public-install verification lane; follow-up #14024
supplies its verifier script. CI at that earlier checkpoint was green
(56 successful checks/statuses, four intentional skips), and the review
is 5/5 with no unresolved findings. Prior feature CI at
`fd73f0a9b1ecdf4094685054028df71739ddc3e1` passed ([run
36148259902](https://github.com/paperclipai/paperclip/actions/runs/36148259902));
that is historical evidence, not a current-head result.

Paid Product measurements use frozen integrated source
`2d939a92b21dcaf5c77c88b54d96784d2ddd0699`, which combines the feature
with #13973, #13977, and #13979. That source passed all 52 CI checks and
clean 5/5 review. Later master syncs incorporate upstream changes. Their
checks remain separate from these pinned live measurements.

| Check | Result and source-pinned report |
| --- | --- |
| Subscription protocol roster | [39/39 first attempts; 206
assertions](https://d1p6rlowie26tp.cloudfront.net/runner-protocol-evals/campaigns/gha-36046839612-1/index.html),
runtime `bc6833f7`, evals `92bb4b8c` |
| API protocol roster | [39/39 first attempts; 206
assertions](https://d1p6rlowie26tp.cloudfront.net/runner-protocol-evals/campaigns/gha-35926577007-1/index.html),
runtime `4a1061c8`, evals `3213dbec` |
| Subscription full Product matrix | [16/16 first attempts; 144
assertions; cleanup
passed](https://d1p6rlowie26tp.cloudfront.net/runner-e2e/campaigns/gha-36096908572-1/index.html),
source `2d939a92` |
| Subscription core repetitions | 18/18: tool use, planning approval,
and Stop/resume each passed three times in local and Daytona profiles.
The full matrix contains repetition one; [repeat
two](https://d1p6rlowie26tp.cloudfront.net/runner-e2e/campaigns/gha-36104551060-1/index.html)
and [repeat
three](https://d1p6rlowie26tp.cloudfront.net/runner-e2e/campaigns/gha-36108100404-1/index.html)
each passed 6/6. Total: 28 unique subscription attempts at `2d939a92`. |
| API smoke and question continuation | [4/4 first attempts; cleanup
passed](https://d1p6rlowie26tp.cloudfront.net/runner-e2e/campaigns/gha-36147315401-1/index.html),
both environments at `2d939a92` |
| Historical API Product coverage | [16/16 full
matrix](https://d1p6rlowie26tp.cloudfront.net/runner-e2e/campaigns/gha-35875144860-1/index.html)
and 18/18 core repetitions at `4a1061c8`; retained as measurements of
that revision |
| Native Daytona proof | Three subscription and three API
MCP/permissions/resume runs passed at `bc6833f7`. Three expired-login
admission and fenced refresh checks passed without inference. All test
sandboxes were removed. |
| Inspectable artifacts and UI | Current-source screenshots verify
planning approval, direct Ask completion, question continuation after
controller restart, and two downloadable project revisions. The project
downloads pass 12 and 18 tests; all 40 independent artifact oracle
checks pass. |
| Provider-free checks | 116 eval-validator tests, 39 Grok definitions,
and 359 enabled/external campaign cells pass. Continuation regressions
above 2 MiB and 16 MiB failed before their fixes; 32 focused
recovery/ownership/size checks pass. |

The 32 unique current-source Product attempts have no failures, retries,
or skipped cells, and all cleanup checks pass. Whole-workflow timing,
model identity, image and provider-pack provenance, attempts, and
accounting coverage are retained in the canonical reports. The report
publisher's conservative `complete=false` flag is preserved; independent
audits verify the exact selected source catalog and immutable result
rows.

Pins: Grok Build `1.0.13 (5e9a58528b76)`, ACPX `0.13.1`, ACP model
`grok-4.7`. Linux binary SHA-256:
`edf79521581bb5e6b95abef848491a6a742e860da3e237ebe86a280d30dce4c1`.
Launcher SHA-256:
`f0b698395a3704ed2ffaf84ea19bdb20c36c8a0a70b7c629c7b6ffe144e59e55`.
Image:
`ghcr.io/paperclipai/paperclip-daytona-runner@sha256:76b24edfd850219e949418b19e4ceba690e84d51d199ade426e484953329b5e9`.
Image build source is `4196a4cd`, recorded separately from application
source `2d939a92`; each campaign verifies the image signature and
provider pack.

Original failed campaigns remain available: [continuation
bound](https://github.com/paperclipai/paperclip/actions/runs/36057718059),
[scheduler/event
capture](https://github.com/paperclipai/paperclip/actions/runs/36071063537),
and [startup cleanup plus EC2
interruption](https://github.com/paperclipai/paperclip/actions/runs/36080870743).
They retain their original grades. No Docker or Rust builds ran on the
developer laptop for these follow-ups.

## Risks

Merge packaging follow-up #14024 with this base before public release.
The follow-up replaces the private Grok bridge package with a built-in
launcher and makes the native binary an explicit sandbox prerequisite.

Three separate, reviewed fixes are part of the tested integrated
behavior: #13973 serializes task-run admission; #13977 captures complete
event evidence; #13979 durably reconciles failed Daytona creation. Each
has green CI and clean 5/5 review. Failed-create recovery has 277 plugin
tests, 92 SDK tests, host-runtime recovery tests, and a real Daytona
lost-deletion-receipt proof. The live proof uses a private file for
journal persistence; database durability is covered by host tests.
Worker death before delivery of a failure envelope remains outside that
recovery mechanism.

Subscription fixtures stage an authorized company login; interactive
browser sign-in is not qualified. Local Product profiles ran on EC2
Linux. The temporary subscription credential was removed from the
protected GitHub environment after all subscription audits, with absence
verified. Runtime homes and refresh copyback remain ownership-fenced.

Protocol results remain pinned to their original revisions; they are not
relabeled as tests of the latest feature commit. New binary/model
versions require qualification. Missing token usage and model cost
remain unknown; runtime estimates do not establish a full bill.
Automatic paid Grok scheduling remains disabled pending separate
reviewed enablement. The 64 MiB bound can increase memory use for
verbose sessions, and larger files still fail closed. No automatic
legacy-agent migration occurs.

## Model Used

OpenAI GPT-6 through Codex, with tool use and code execution. The exact
serving model identifier 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-09-28 13:54:36 -05:00
e006c18f20 test(paperclip-runner): stabilize the assigned-skills ACPX runtime host test (#13453)
Release sealed skill homes before test cleanup and reuse one prepared sandbox across the assigned-skills test opens. Preserve the current skill-refresh and prompt assertions without increasing test timeouts.

Co-Authored-By: Devin Foley <devinfoley@users.noreply.github.com>
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-09-24 11:11:02 -07:00
Devin FoleyandPaperclip be6f49a425 feat(runner): refresh shared coding harness runtimes (#13838)
## Thinking Path

> - Paperclip runs agents through local adapters and the native runner.
> - Both paths must use the same installed provider CLI.
> - New models require current harness releases.
> - The runner still pins Codex 0.153.4, Claude SDK 0.3.263, and
OpenCode 1.18.29.
> - Changing the image alone would fail the runner's exact version and
executable checks.
> - This pull request updates those dependencies, integrity checks,
controller checks, and image pins together.
> - Shared installations can then run the current models without a
task-time download.

## Linked Issues or Issue Description

Refs #13829, which updates model choices and reasoning controls.
Searches found no open PR that updates these runtime pins.

**Current behavior**

The shared provider pack ships old CLIs. Claude Code 2.1.263 cannot run
Opus 5.5, which requires 2.1.280. Remote controllers reject provider
packs whose versions differ from their declared pins.

**Proposed behavior**

Use Codex 0.156.0, Claude Agent SDK 0.3.280 / Claude Code 2.1.280, and
OpenCode 1.18.32 throughout the runner. Keep the reviewed ACP bridge
patches and one shared CLI installation per provider.

**Reason and benefit**

Current harnesses support the new model IDs while preserving executable
verification and remote provider-pack compatibility checks.

## What Changed

- Update dependency overrides, the Codex ACP package patch, runtime
profiles, and remote controller pins.
- Verify the new Claude Linux x64 and macOS arm64/x64 executables and
Codex Linux x64 executable against integrity-verified npm archives.
- Refresh OpenCode version checks, fixtures, and the runner
configuration label.
- Refresh the eval image's Grok, Gemini, Kimi, Cursor, and GitHub CLI
pins and archive hashes. Hermes remains current at 0.19.0.
- Refresh the build-time lock digest from clean pnpm 9.15.4 resolution.
Leave lockfile commits to repository automation.
- Document model compatibility and the separation between CLI runtimes
and patched ACP bridges.

## Verification

- `pnpm -r typecheck` and `pnpm build` passed.
- Rust workspace release tests passed.
- Package/patch and OpenCode binary-materialization contract tests: 11
passed.
- Real Codex 0.156.0 startup-ownership and paginated session-resume
probes passed with isolated synthetic homes and no model turn.
- Codex app-server `thread/start` preserved `gpt-6-sol` and
`gpt-6-luna`; no `turn/start` was sent. An unauthenticated built-in
catalog does not include those account-served entries.
- Installed Claude integrity probes passed for `claude-opus-5-5` and
`claude-fable-5-1`.
- `pnpm --filter @paperclipai/paperclip-runner
test:opencode:qualification` passed with the actual OpenCode 1.18.32
executable under Node 24 and Node 25. The loopback provider exercise
covers health/version, session creation/read/delete, SSE, and a
completed async prompt.
- `pnpm check:token-gates` passed.
- The targeted runner suite passed 130 tests. Three macOS failures in
snapshot module lookup and OpenCode final-message selection also
reproduce on the unchanged base; Linux CI will provide the platform
check.
- [Final Linux
CI](https://github.com/paperclipai/paperclip/actions/runs/35798076399):
all gates passed. Four jobs needed one retry after their CI workers
received shutdown signals. The PR has 55 successful checks, two skipped
checks, Greptile 5/5, and no unresolved review threads.
- Changed runner configuration UI tests: 5 passed.
- Full macOS `pnpm test:run` reached 13,094 passing server tests, 84
skipped, and 18 failures before the wrapper stopped. Failures involved
skill-cache publication permissions, missing bundled connector skills in
the worktree, and a conversation-reset timing case. The 10 cache
permission failures reproduce on the unchanged base; both
conversation-reset cases passed on a targeted retry. The wrapper did not
reach its later workspace/serialized groups locally; Linux CI covers
those groups.
- The local Docker daemon did not respond, so no local Docker build was
run. No billable model requests were made.

## Risks

- Deploy the matching controller and provider pack together. Older
controllers enforce their previous exact pins.
- Current upstream CLIs can change behavior. Existing protocol tests and
isolated real Codex probes cover the integration boundaries;
authenticated model inference is not part of these checks.
- ACP bridge package versions and executable digests stay unchanged
because their executable bytes are unchanged. Only the underlying
CLI/SDK dependencies move.
- No schema migration. Revert the runtime and image pins together to
roll back.

## Model Used

OpenAI GPT-6 via Codex, with repository tools, code execution, and web
research. The exact serving model ID and context window were not exposed
by 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 for the changed surfaces
and real-executable probes; full macOS-suite limitations are listed
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-09-22 17:02:29 -07:00
DottaandPaperclip 7bc03e0acd feat(runner): default harnesses to full auto and support task reassignment (#13686)
## Thinking Path

> - Paperclip lets people manage AI agents and their work.
> - Agent Chat uses native runners to save plans and coordinate tasks.
> - Provider defaults differed across harnesses and could stop
unattended work at a second permission gate.
> - Agents also lacked a dedicated tool to move existing work to another
agent safely.
> - This change defaults native providers to full automatic permission
for provider tools and connected tools.
> - A guarded reassignment tool preserves task identity, stops the
previous run, and schedules the new owner once.
> - Codex and Claude chat acceptance tests now use production permission
defaults.

## Linked Issues or Issue Description

**Subsystem affected**

Native runner, ACPX Claude permission policy, task authority, and Agent
Chat acceptance tests.

**Problem or motivation**

A user can authorize an agent to save a plan or create a task, but
Claude's default provider gate can still stop that action. Reassignment
needs a dedicated operation that preserves context and avoids concurrent
owners or unintended recovery runs.

**Proposed solution**

Default Claude/ACPX to `approve-all`, OpenCode to `allow`, and Codex to
`never`. Apply the defaults at configuration, execution, fresh-session,
resume, driver, and proxy boundaries. Keep explicit permission settings
and server-side company, claim, task-mode, and approval checks. Add
`reassign_task` with version checks, durable idempotency, audited
cancellation, and guarded successor scheduling.

**Alternatives considered**

A Paperclip-only allowlist still blocks provider tools and other
connections during unattended work. Full automatic permission is the
requested product default. Recreating a task discards its identity and
history. Updating assignment without stopping the previous run can leave
two agents working on the same task.

**Roadmap alignment**

This extends the existing planning, delegated work, governed tool
access, and recovery features. It adds no new service or schema
migration. Recent related tasks and open PRs were checked for duplicate
work.

**Additional context**

Related: #13678 (Agent Chat tools and recovery), #13677 (remote runner
startup). The stacked legacy-adapter companion is #13693. This also
fixes the deployed-server artifact fallback needed to stage the current
runner binary.

## What Changed

- Default Claude/ACPX to `approve-all`, OpenCode to `allow`, and Codex
to `never`, including missing settings at direct driver and proxy entry
points. These defaults cover provider tools and connected tools.
Preserve explicitly configured restrictive modes.
- Include assigned approval reads using canonical side-effect
classifications, so verifying a recorded approval does not trigger
another provider gate. Paperclip approval decisions still enforce
controller authority.
- Carry the new permission mode through server configuration, execution
contracts, recovery identity, TypeScript, and Rust. Keep
`approve-paperclip` as an optional restricted mode, with exact SDK rules
and closed unknown requests. It is not a default.
- Add `reassign_task` to the semantic catalog, controller, mock
authority, and generated contracts.
- Guard reassignment with company authorization, expected owner and
version, protected-state checks, and durable retry receipts.
- Honor explicit backlog task creation atomically with the initial plan,
without scheduling a wake. Preserve backlog holds regardless of
dependency readiness.
- Stop active work before changing ownership. Restore the prior owner
through a guarded, idempotent wake if final handoff validation fails.
Keep intentional reassignment stops out of failure recovery. Preserve
backlog and blocked states without waking them early.
- Add authorization, concurrency, replay, stop, and permission boundary
regressions. Add Codex and Claude chat reassignment cases and run native
chat cases with production defaults.
- Clarify shared runner guidance: save plans and Paperclip documents
directly with `write_document`; create and register a local file only
when a downloadable file is requested.
- Document provider defaults and the operator choices for existing
agents.

## Verification

- Current head `d82fbb0f03546d27cecf072250e4172e0b1ee662`: **55 checks
passed**, with two intentional skips. [PR
checks](https://github.com/paperclipai/paperclip/pull/13686/checks).
- Greptile reviewed that exact head at **5/5**. The security reviewer
acknowledged the intended full-auto default, and the acknowledged
discussions are resolved.
- Full workspace `pnpm -r typecheck` and `pnpm build` passed locally
after rebasing onto current master. Targeted adapter/server, runner,
API, default/resume, and heartbeat configuration tests passed.
- **All six real-provider acceptance cases passed on their first
attempt, with cleanup passing:** plan handoff, task reassignment, and
backlog creation/status, each on native Claude and Codex. Evidence
records Claude's effective `approve-all` mode. [Campaign and
downloadable
evidence](https://github.com/paperclipai/paperclip/actions/runs/35469926548).
- The live campaign tested combined revision
`a37881c824dcd7170380fc4b788732fc743e5da7`. The final PR heads add only
a heartbeat test expectation correction; application code is unchanged
from that live-tested revision.
- The campaign's result-enforcement job passed. Its separate report
publisher failed because the trusted workflow's `patchedDependencies`
configuration differs from its frozen lockfile. All six results and
screenshots remain available as GitHub artifacts. The overall manual
workflow is red for this publishing failure.
- Full-suite coverage is supplied by the passing CI partitions. The
separate unsharded local run was stopped after the corresponding CI
partitions passed; it is not counted as a completed local run.
- Reassignment tests cover stale state, cross-company access, denied
authority, cancellation failure, compensating wake, and idempotent
retries. Backlog tests verify the original creation audit, saved plan,
exact task count, and absence of task-bound runs.

## Risks

- Agents with no explicit permission mode now receive full provider tool
permission, including connected tools. This is a deliberate broad
default. Existing explicit restrictive modes still apply. Controller
authorization, company isolation, workspace boundaries, and Paperclip
governance remain in force.
- Reassignment crosses run cancellation and task ownership transactions.
Durable stop intent, revalidation, audit receipts, and guarded queue
dispatch cover interruptions and retries.
- The new permission enum requires a current runner artifact. The remote
artifact fallback uses the same resolved controller binary for upload
and execution.
- Live provider behavior remains subject to the selected model. Targeted
live results do not qualify the full catalog.

## Model Used

OpenAI Codex, based on GPT-6, with code execution and repository tools.
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-09-19 16:49:18 -05:00
DottaandPaperclip c1f6c3310a fix(runner): repair catalog runtime and grading boundaries (#13676)
## Thinking Path

> - Paperclip manages tasks across persistent agent sessions.
> - The full Runner E2E catalog exposed failures in session restoration,
tool validation, and test controls.
> - These failures prevented valid work from resuming or made a valid
interaction fail the test.
> - Invalid completion reports also reached finalization before the
provider received useful feedback.
> - This pull request repairs those boundaries without changing
production prompts or approval policy.
> - Focused regressions and fresh paid cases verify each fix.

## Linked Issues or Issue Description

Follow-up to #13655. Stacked on the trusted worker prerequisite fix in
#13674.

**What happened?**

Read-only skill uploads failed in resumed Daytona sandboxes. Invalid
criterion IDs escaped tool validation. A progress event could park a run
before its tool response settled. Partial question forms hid required
answers. Two test assumptions rejected valid plan keys or failed to
navigate an optional question page.

**What did you expect to happen?**

Resume identical skill bundles, give repairable feedback for malformed
completion calls, preserve in-flight tool responses, show all required
questions, and test the rendered workflow accurately.

**Steps to reproduce**

Inspect the failed cases in
https://github.com/paperclipai/paperclip/actions/runs/35417932353. Fresh
campaigns:
https://github.com/paperclipai/paperclip/actions/runs/35444497313 and
https://github.com/paperclipai/paperclip/actions/runs/35445327618. The
later backup cleanup is tested in
https://github.com/paperclipai/paperclip/actions/runs/35446477285.
Combined report:
https://pages.paperclip.ing/runner-e2e-operational-35444497313/investigation.html.

## What Changed

- Compare immutable archives before reusing read-only Daytona bundles.
Reject corrupted content and preserve unrelated files.
- Validate exact criterion IDs before accepting completion. OpenCode
returns a tool error instead of emitting a result that terminates
runnerd.
- Complete the activity item for rejected OpenCode calls.
- Remove retired read-only harness backups without altering live files
or following symlinks. A fresh paid rerun exposed this later
checkpoint-cleanup failure.
- Exclude progress messages from the governed-wait completion boundary.
- Reject newly created question forms that omit questions or contradict
their stored answer semantics. Keep historical rows readable.
- Navigate all rendered question pages and recognize revision-bound
descriptive plan keys in the continuation suite.

## Verification

- Harness unit suite: 383 tests pass. Harness typecheck passes.
- Native session executor and status corpus: 381 tests pass.
- Shared question and interaction-service tests: 42 pass; native
question bridge and executor: 360 pass. Daytona sync: 21 pass, including
foreign-owner archives and corrupted immutable content.
- OpenCode driver: 29 tests pass, including wrong, missing, and
duplicate criterion IDs followed by a valid retry.
- Repository typecheck and build pass. The later OpenCode activity fix
also passes its package build.
- The latest commit passes all 52 PR checks and Greptile 5/5. The
backup-cleanup fix also passes 351 related local tests and server
typecheck. Local full-suite coverage completed across runs.
adapter-auth-signal-routes and pipelines-routes encountered transient
socket resets; both pass on retry, and all remaining 24 serialized files
pass. Paid reruns are complete: 27 of 29 unique cases pass using the
latest recording per case. Both Daytona controller-restart cases still
fail with runner_state_identity_mismatch; the report describes this
remaining runtime issue. Eight affected cells need #13674 on master
before their rerun.

## Risks

Creation rejects inconsistent dual question representations but does not
change historical records. Immutable bundle comparison must verify bytes
before skipping extraction. Completion feedback must use the contract
bound to the current run. Durable suspension and approval checks remain
enforced. Production prompts are unchanged.

## Model Used

OpenAI GPT-6 via Codex, with repository inspection, code editing, and
test execution. The exact API 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-09-19 09:27:48 -05:00
DottaandPaperclip 36dbb7ed1c fix: harden agent chat runner tools and recovery (#13678)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Agent Chat turns discussion into plans, tasks, reviews, and hires.
> - These workflows need reliable tool results and task context on the
native runner.
> - Live Claude and Codex tests exposed lost retry requests, invalid
project inputs, and a child startup crash.
> - Recovery also exposed a misleading retry action and missing child
task context.
> - This pull request fixes those paths and adds regression coverage.
> - Agents can continue the original request and operators can inspect a
stopped run.

## Linked Issues or Issue Description

**What happened?**

A failed Agent Chat retry could lose the user's question. Project
creation accepted unsupported icons in its tool schema. Codex could stop
when a helper's MCP startup event arrived before its thread lineage. A
stopped task offered Retry even when the server required execution
reconciliation. Resumed agents could miss existing delegated tasks.
Hiring and review instructions did not describe the native runner's
available tools and source requirements.

**Expected behavior**

Retries retain the selected request. Tool schemas match the API. Child
startup information does not gain authority over the parent or stop it.
Recovery actions match the server's requirements. Task context exposes
existing child work. Handoffs contain the material the assignee needs.

**Steps to reproduce**

1. Enable experimental Agent Chat in an isolated development instance.
2. Configure native Codex and ACPX Claude agents on Paperclip Runner.
3. Ask for a plan, revise it, approve task creation, and request a hire
and status report.
4. Retry a failed chat turn and check that it answers the original
request.
5. Start a Codex helper before its thread lineage arrives.
6. Resume a delegated task and inspect its existing children and saved
output.

**Paperclip version or commit**

The live failures were found at `f2c5e54dc`. This branch is rebased onto
`86b7ee992`.

**Deployment mode**

Isolated local development instance with native Codex and ACPX Claude.
No database migration or default permission change.

Related work: Refs #13284 for Agent Chat. Refs #13438 for the
server-side API receipt fix, which this branch preserves. The transport
also accepts the earlier HTTP receipt format. Refs #13655 for the
current Codex continuation and helper lineage handling, which this
branch also preserves.

## What Changed

- Preserve failed Agent Chat wake-comment IDs and session generation
from the authorized source run. Reject pre-reset retries.
- Wrap API receipts with the correct semantic call identity. Test
current and earlier receipt formats through real HTTP and runnerd.
- Classify early child MCP startup notifications as information. Keep
foreign completion and result events rejected.
- Constrain project icons on both tool surfaces and regenerate the
protocol contracts.
- Include bounded, company-scoped visible direct child tasks in task
context. Filter hidden tasks before applying the limit.
- Replace the rejected Retry action with Inspect run for native
continuation reconciliation.
- Update hiring, review handoff, status reporting, and development
guidance.

## Verification

- Live tests covered Claude and Codex questions, plan revisions,
approval, task creation, hiring, status, chat reset, failures, and
recovery.
- The recovered task produced its saved checklist and example. A later
follow-up read the existing child tasks and document without creating
more work.
- Full build, repository type checks, token gates, 142 focused tests,
188 runner TypeScript tests, and the Rust notification/descendant
regressions passed after rebase. The separate local full-suite run was
stopped after the complete CI suite passed.
- Review fixes passed the updated route, tool-authority, and icon
regression tests plus server type checking.
- Required commands: `pnpm build`, `pnpm -r typecheck`,
`PAPERCLIP_IN_WORKTREE=false pnpm test:run`, and `pnpm
check:token-gates`.
- At `4ce8047b0`, all 55 applicable GitHub checks pass (two Storybook
checks are intentionally skipped), including the complete
general/serialized test matrix, runner tests, browser tests, build, type
checks, Docker checks, and canary dry run.
- Fresh Greptile review is 5/5 on `4ce8047b0`; all three findings were
fixed with regressions and there are no unresolved review threads.
- Two initial CI service-startup timeouts passed unchanged in local
reproductions and in the latest CI run.

## Risks

- The new event classification is limited to MCP startup information. It
does not authorize foreign task completion, results, or tool requests.
- Task context returns at most 100 direct child tasks and reports
truncation. It excludes hidden tasks and other companies. This improves
delegation context but does not enforce semantic duplicate detection.
- Native reconciliation still requires an operator to inspect and record
prior outcomes. The new link does not replace the recovery API.
- API tools remain opt-in. Claude permission choices remain explicit. No
default permission, schema, or workflow changes.

## Model Used

OpenAI GPT-6 in Codex, with reasoning, repository editing, code
execution, API tools, and browser testing. The exact deployment
identifier and context-window size are not exposed in this session. Live
acceptance agents used OpenAI `gpt-5.6-sol` and Anthropic
`claude-sonnet-4-6`.

## 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-19 09:11:04 -05:00
DottaandPaperclip 43acbcc398 fix(runner): preserve sessions and complete question and approval continuations (#13655)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - The native runner connects task state to provider sessions.
> - Follow-up turns must retain provider memory and carry new user
direction.
> - Lost session IDs caused repeated context and extra input tokens.
> - Native question answers and approval races could leave valid work
blocked.
> - This pull request repairs those paths and adds regression coverage.
> - Agents can continue accepted work without repeating the conversation
or losing the user's answer.

## Linked Issues or Issue Description

Refs #13574. That merged PR shortened continuation prompts and moved
question instructions into tool documentation. This change preserves
sessions and fixes failures exposed by broader testing. Related runtime
work: #13408 and #13410.

**What happened?**

Native follow-up turns could lose the provider session ID. Completion
guidance could replace the original task with its latest comment. Claude
native questions could remain pending after the user answered. Approval
during a running tool call could suspend the run before the tool
response arrived. Onboarding and chat handoff instructions also caused
repeated planning or missing plan documents.

**Expected behavior**

Reuse a valid provider session. Send only new events when that session
already has the history. Preserve the task requirements and apply later
user direction. Store the question answer and deliver it to the waiting
run. Finish governed tool responses before suspending. Execute the
accepted plan without asking for the same approval again.

**Steps to reproduce**

Run the continuation, local-session-integrity, first-task, and
agent-chat suites with native Codex and Claude. Include
provider-question-bridge, accept-while-running, and plan-handoff.

**Paperclip version or commit**

This branch is based on master d54b75011. The active full catalog run
tests 4e75881db. Later review fixes have separate regression coverage.

**Deployment mode**

Isolated local instances and Daytona sandboxes in the existing Runner
full-stack E2E harness.

## What Changed

- Retain provider session identity across turns and late usage
snapshots. Send new continuation events on session reuse, with full
context available for a fresh session.
- Preserve task requirements and later direction in completion guidance.
Return the current contract revision after a stale completion
submission.
- Bridge native Claude questions to saved Paperclip cards. Submit
answers through the saved card and resume the same run.
- Delay governed suspension until tool results settle. Add a
deterministic test barrier for approval during an active run.
- Clarify free-text question examples, explicit onboarding plans, and
execution of accepted chat plans.
- Fix continuation readiness, verified output evidence, and declared
screenshot collection.
- Qualify the legacy Claude test CLI at 2.1.277. The old 2.1.19 CLI did
not discover mounted skills. Update the existing workflow pin and
isolated launcher together.
- Refresh the Daytona image lockfile integrity pin after reviewing
master patch updates.
- Carry continuation mode as runtime metadata instead of inferring it
from user-visible text. Install the test Claude CLI without lifecycle
scripts.

## Verification

- Targeted paid verification: 20/20 cases passed across
local-environment campaigns before the rebase.
[Report](https://pages.paperclip.ing/runner-e2e-seven-fixes-35397904249/).
- Harness checks: 379 unit tests passed; harness typecheck passed.
- Latest-head PR checks: 55 passed, two intentionally skipped. Greptile
is 5/5; the security scan passes.
- Review regressions: 350 executor tests and 204 session/driver tests
passed. A script-free Claude install was verified with the actual CLI.
- Full catalog, including the explicit-only everyday suite: [run
35417932353](https://github.com/paperclipai/paperclip/actions/runs/35417932353).
Completed: **164/205 passed; 41 failed**. [Full dashboard and failure
investigation](https://pages.paperclip.ing/runner-e2e-full-catalog-35417932353/).
Includes 204 case artifacts and one pre-case GitHub authorization
timeout; missing evidence is not scored as a pass. The full run tested
`4e75881db`; Final-head metadata/CLI smoke cases both passed. In the
separate [six infrastructure
retries](https://github.com/paperclipai/paperclip/actions/runs/35419769343),
the GitHub timeout case passed and all five Docker preflight failures
repeated. [Follow-up
dashboard](https://pages.paperclip.ing/runner-e2e-full-catalog-35417932353/follow-up/).
- Full local typecheck and build passed on the rebased branch. The full
local unit run completed with 657 passing files, two test timeouts and
one suite setup timeout. All three affected files passed when rerun in
isolation (84 tests). The first full local run was not clean.
- Focused regression coverage includes the live question bridge,
same-run response delivery, UI routing, stale revisions, approval
overlap, and session reuse.

## Full-catalog follow-ups

- Test infrastructure: 14 Claude everyday cells probe an absent host
CLI; six cells failed pre-task GitHub/Docker qualification (GitHub
passes on retry; all five Docker cases repeat; the workflow preflight
allowlist omits their case IDs); five ACPX Codex cells cannot create
sandbox namespaces.
- Runtime: four OpenCode completion-criteria mismatches masked by
shutdown errors, one service-approval suspension failure; three Daytona
recovery failures encounter existing skill files; one duplicate
completion wake.
- Confirmed test defects: question pagination and a noncanonical plan
document key.
- Product/behavior: mismatched visible/required question sets, an
attachment instead of the requested task document, one lone-option
onboarding question, early completion instead of review, and a Codex
Mini completion-schema failure.
- The report job itself fails on trusted master’s stale patch/lock
configuration. The linked report is rebuilt with the shared renderer
from original cell results and public fixture screenshots; it excludes
private snapshots, logs and traces.

These are investigated follow-ups, not silently regraded passes.
First-task passed 51/52. The PR checks are green independently of the
broader catalog’s behavioral/infrastructure failures.

## Risks

- Session reuse depends on a valid provider identity and context
coverage. Fresh-session fallback and reset tests cover this boundary.
- Native question delivery spans saved interaction state and a live
provider run. Tests cover duplicate events, closed runs, and same-run
answers.
- Provider behavior varies. The full paid catalog may expose failures
beyond these targeted fixes; those results will be reported without
relaxing valid approval or output checks.
- The legacy Claude version update is limited to test infrastructure. No
database migration is included.

## Model Used

OpenAI Codex, GPT-6 family, with repository inspection, code execution,
and browser/E2E tools. The exact runtime model identifier 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 (targeted checks and all
three timeout-file reruns pass; full-run timeout caveat 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-09-19 07:42:57 -05:00
DottaandPaperclip 84fe89906d fix: complete native agent review handoffs (#13581)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - Native execution uses durable runs, issue locks, wake requests, and
typed tool authority
> - A child can finish with a native agent review request while its
original assignee stays responsible for the work
> - The reviewer then needs a bounded execution path that can inspect
the child, record one decision, and finish safely
> - Before this change, assignee-only gates rejected the reviewer or
left the parent waiting after the child review ended
> - This pull request adds typed reviewer admission, scoped reviewer
tools, durable wake and recovery handling, and parent continuation
evidence
> - The benefit is that native review handoffs complete without changing
child ownership or granting broad mutation access

## Linked Issues or Issue Description

Refs: #13314
Refs: #13574

**What happened?**

A native child run could report `needs_review` for an agent reviewer.
The reviewer wake then failed assignee and execution-lock checks. The
child remained in review and the parent remained waiting.

**Expected behavior**

The named reviewer should receive one durable wake. The reviewer should
inspect the child and resolve the exact review card. The child assignee
should stay unchanged. The parent should receive the recorded review
outcome after the child reaches its terminal state.

**Steps to reproduce**

1. Run a native task with a different named agent reviewer.
2. Keep the child assigned to its original worker.
3. Let the worker finish with a native completion review request.
4. Start the durable reviewer wake.
5. Resolve the review and finish the reviewer run.
6. Observe the child and parent state.

**Paperclip version or commit**

Base: `e926b1301`. PR head: `b31ad9ab8`. Live reviewer verification
source: `eea171aae`.

**Deployment mode**

Built from source.

**Installation method**

Built from source (pnpm build).

**Agent adapter(s) involved**

Not adapter-specific (core bug).

**Access context**

Both.

**Database mode**

Embedded PostgreSQL in the isolated live test fixtures.

## What Changed

- Add server-validated native review assignment facts.
- Admit only the exact company, issue, source run, decision, revision,
addressee, and resolver policy.
- Give reviewer runs a narrow set of Paperclip read and resolve tools.
File and shell access follow the configured agent and environment
policy, so reviewers can run tests.
- Separate server-owned reviewer instructions from untrusted persisted
review data. Escape the data boundary; retain server-enforced
authorization.
- Keep the child assignee unchanged. Atomically claim the reviewer run,
wake request, and issue execution lock. A competing lock prevents
provider startup.
- Require the exact running reviewer session and current issue lock to
resolve its assigned card. Reject missing, unrelated, or terminal
reviewer runs.
- Add durable reviewer wake, lock, stale-card, and abandoned-run
recovery handling.
- Prevent duplicate native wake dispatches during deferred admission and
recovery.
- Carry accepted or rejected child review outcomes into parent task
context and continuation evidence.
- Add focused server, runner, and native protocol coverage.
- Preserve upstream continuation rules. Add child review decisions as
separate evidence, while keeping real human answers in their own field.
- Return actionable completion validation feedback to both providers.
Permit a corrected completion after rejection. Keep strict terminal
acknowledgment validation.
- Apply exclusive shared-workspace locks to sandbox environments. Local
and SSH folders can run concurrently, including when old settings
request serialization.
- Repair test timing, native event parsing, and the review artifact
assertion. Allow a valid reject, correct, and accept review sequence.
Check the accepted card against its reviewer run and decision. Keep
polling within the existing deadline when review acceptance precedes the
parent wake projection; report a specific missing-continuation error at
timeout.
- Apply the ACPX pending-call limit to reserved finish/block calls, with
capacity-release and cancellation tests.

## Verification

- `pnpm build`: passed on `eea171aae`.
- `pnpm -r typecheck`: passed on `eea171aae`.
- `pnpm test:e2e:runner:unit`: 359 tests passed in 30 files on
`b31ad9ab8`; runner E2E typecheck also passed.
- `pnpm check:token-gates`: passed.
- Focused DB review, reviewer authority, and prompt-boundary checks: 31
tests passed. They cover invalid reviewer runs, competing locks, atomic
admission, duplicate claims, and valid resolution.
- Heartbeat, workspace, and recovery checks: 30 tests passed.
- ACPX sidecar suite: 27 tests passed. Moving the capacity guard back
below reserved handling makes both new regression cases fail.
- Four focused live continuation checks passed on their first attempt at
`f15f55e0a`: answer updates scope (6/6 each on Codex and Claude) and
question tool guidance (12/12 each). These cases do not use the reviewer
prompt path changed afterward.
- Fresh Codex and Claude review-handoff checks passed all 29 native
checks each on their first attempt at `eea171aae`. Both runs received
the expected fixed prompt and completed cleanup. Only the six selected
live flows were tested; no full paid provider catalog run.
- The final commit only extracts the existing test-harness timeout
diagnostic into a shared helper and adds positive and negative coverage.
Removing the accepted-review guard makes two regression assertions fail;
restoring it passes all six timeout tests. Production runtime code,
prompts, deadlines, and grading criteria are unchanged by this final
commit.
- Deadline regressions: a valid continuation delayed 20 seconds succeeds
within its 30-second unit-test deadline; an absent wake returns a
specific candidate-failure diagnostic at that same deadline. Both
assertions failed before the fix. Production E2E deadlines remain
unchanged.
- Historical native failures remain recorded: Docker availability
failures; a valid reject/correct/accept sequence that the first-card
grader misread; and a test that rejected the gap between accepted child
review and parent wake projection. No failed result was regraded. The
latest tests use a protected reference to the pinned Docker image and
the unchanged artifact oracle and time limits.
- Full repository verification runs in GitHub CI. Local verification
uses the focused suites above, full build, and full typecheck. An
unchanged Codex shutdown timing test failed once in CI, passed in
isolation, and its full shard passed on the final commit without changes
to that test or its causal code path. The original failure is retained
in the verification record. Greptile reviewed `b31ad9ab8` at 5/5 with no
outstanding actionable findings. All review threads are resolved. All
current-head CI gates passed, including the isolated native runner
Docker build (55 successful checks; two skipped by the workflow).

## Risks

- Reviewer admission depends on exact persisted decision and interaction
bindings. A stale or changed card is rejected.
- Paperclip control-plane tools are limited to inspection and review
resolution. This is not a filesystem permission boundary; provider file
and shell access retain the configured policy.
- Deferred wake recovery changes dispatch receipt coalescing. A
scheduler regression could delay a continuation if the receipt state is
wrong.
- Parent review outcomes are evidence for the model. They do not grant
tool authority or change issue ownership.
- This change does not address legacy lease-hold handoff behavior.

> Roadmap review: native execution, review gates, and durable recovery
are existing roadmap capabilities. This PR completes a narrow
reliability path for those capabilities.

## Model Used

OpenAI `gpt-6-astra` with reasoning, tool use, and code execution.
OpenAI `gpt-5.6-luna` assisted with bounded implementation, review, and
journal work. Context window size is not exposed by this session. Live
test subjects use `gpt-5.6-sol` and `claude-sonnet-5`; they are not the
PR authors.

## 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-17 15:52:19 -05:00
DottaandPaperclip 11921075a4 Add first-task onboarding skill and Runner E2E coverage (#13517)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - The first task helps a new user define and approve useful work.
> - That workflow needs reusable instructions and tests against the
production experience.
> - Native Codex and Claude must load the assigned skill, including
after resume.
> - Maintainers need recorded conversations and precise failed checks to
judge regressions.
> - This pull request adds the first-task skill and a suite in the
shared Runner E2E harness.
> - It keeps behavior results separate from informational quality scores
and incomplete recordings.

## Linked Issues or Issue Description

**What existing behavior does this improve?**

The first onboarding task and the Runner E2E report used to review it.

**Current behavior**

Onboarding embeds its policy in a hidden brief. Native Codex drops the
skill-instructions setting at the Rust boundary. The shared E2E harness
has no onboarding suite or full conversation view.

**Proposed behavior**

Assign and invoke `/first-task` for the onboarding task. Send selected
Codex skills as structured protocol inputs. Run twelve scenarios across
legacy Codex, legacy Claude, native Codex, and native ACPX Claude.
Include all 48 cells in full campaigns. Show recorded chat, question and
approval cards, exact checks, instructions, and billing in the shared
dashboard.

**Reason and benefit**

Measure the real onboarding experience before changing prompts.
Distinguish infrastructure failures, behavior failures, and unexercised
journey steps.

**Breaking changes**

No database migration or production API change. First-task instructions
now live in an assigned skill. The user-edited persona is preserved; the
skill includes the maintainer-approved proposal-mode mapping and
saved-plan requirement.

Related: #11043 is earlier onboarding work. #13422 already fixes native
Claude model pinning, context delivery, and read permissions on master;
this branch includes those fixes through its base. The new Claude
recovery test supplements them.

## What Changed

- Extract and assign the first-task skill while retaining the production
greeting and opening question.
- Carry the Codex skill-instructions flag through thread start and
resume. Resolve explicit task skill references only against assigned
skills and send native skill inputs.
- Invoke an unambiguously selected assigned skill through Claude ACPX’s
native slash-command parser on initial and resumed turns, retaining the
entire task/wake envelope as its argument. Do not carry that invocation
into ordinary tasks.
- Restore the saved single-task proposal modes: confirmation card, or
saved plan with revision-targeted checkbox approval. Explicit plan
requests also require a saved plan.
- Add first-response and complete-journey cases with fixed user facts,
acceptance checkpoints, durable outcome checks, and accounting for child
runs.
- Fail the eval when choice questions have fewer than two real options.
Recognize planning documents without treating them as completed work.
- Add optional, bounded quality judging as explicit post-processing.
- Render full conversations and static interaction cards in the shared
report. Conversations start folded. Show original and regraded results
and incomplete journeys distinctly.
- Keep credential-persistence scanning outside the first-task behavioral
suite; retain public evidence redaction.
- Refresh generated capability references after the API-reference edits.
- Correct shared native question guidance and tool schemas: choices need
at least two meaningful options; open-ended questions use canonical text
fields with the required compatibility payload. Verify both formats
through real tool-authority persistence.
- Disable announcements automatically for every isolated Runner E2E
process and label the gallery environment/provider/target explicitly.
- Remove CI races in the GitHub connection browser test and native
session recovery test by waiting for the actual async work before
asserting its results.

## Verification

- `pnpm exec vitest run
server/src/services/onboarding-first-task-assets.test.ts
server/src/__tests__/issue-onboarding-first-task-routes.test.ts`: 19
passed.
- `pnpm --dir packages/paperclip-runner exec vitest run
src/drivers/acpx/runtime-host.test.ts
src/drivers/acpx/native-skill-prompt.test.ts
src/cli/acpx-runtime-sidecar.test.ts`: 70 passed. Native command
forwarding and the 1 MiB input boundary both failed before their fixes
and passed afterward. Coverage includes changed skills on reopen,
approval context, and an ordinary subsequent task.
- Runner E2E unit suite: 306 passed. Harness typecheck passed. The 64
first-task fixture and grader tests also pass.
- Full repository typecheck and build passed locally. Server typecheck
and Runner build passed again after the native-command change.
- Full GitHub Actions CI passed on `23e56447b`: all
server/workspace/browser shards, Runner verification, typecheck/release
registry, build, canary, policy, and Docker checks. Greptile reviewed
this exact head at 5/5 with no unresolved threads. The earlier broad
local run had database startup/timing failures that passed isolated
retries; the complete remote suite is green.
- Merge verification against current master: 312 harness tests and 13
native recovery tests passed. Regenerated semantic contracts and fixture
hashes pass their consistency check. Full local typecheck and build also
passed on the stacked queue branch. After merging the latest master and
preserving the GitHub setup timing regression in the split browser
suite, both focused GitHub browser tests passed. Three CI timing/startup
flakes passed local verification and one remote retry; all latest-head
checks are green.
- Real pinned Claude SDK and Claude ACP JSON-RPC probes against a local
mock API confirmed that `/skill-name` expands the assigned skill body
before the model request and retains the task arguments. A prose mention
does not. The probes made no paid model calls. The ACP probe used the
current first-task skill body and retained the wake arguments.
- [Full 48-case campaign and
report](https://pages.paperclip.ing/runner-e2e-first-task-35053063880/):
44 passed after three interrupted Codex cases completed in targeted
reruns. Original results, regrades, and all 51 executions remain in the
report provenance.
- [Claude campaign after the shared-question
fix](https://pages.paperclip.ing/runner-e2e-first-task-claude-35099525201/):
10/12 passed with zero single-option failures. All 12 recorded the
current assigned skill and corrected guidance. The failures exposed
skipped skill invocation and a missing saved plan. This PR adds native
command invocation and explicit saved-plan instructions; the subsequent
report below still shows behavior failures.
- [Fresh 12-case Claude
report](https://pages.paperclip.ing/runner-e2e-first-task-claude-35102737804/)
at `78452129e`: 10/12 pass after correcting two false proposal-matcher
failures. The recordings said “Here is the task I will create and
run/complete” in approval cards; the old matcher missed that word order.
Regression tests failed before the fix and pass after it. Original
results and offline regrade provenance remain linked. No agent rerun was
needed. Zero single-option-question failures; two behavior failures
remain: direct work before acceptance on a plain first message, and an
explicit plan request without a saved plan. Neither check was relaxed.
The follow-up `82087ac7e` fixes command-prefix size accounting;
`94aefb1f3` fixes only that proposal matcher.
- Report browser checks confirm folded conversations, rendered cards,
explicit Local/Daytona labels, and no page errors. The published-object
audit scanned 1,306 text files across 2,154 objects with no
credential-format findings or prohibited files. Image pixels and unknown
token formats are outside that scan.

## Risks

- Model behavior is nondeterministic. One campaign is evidence, not a
guarantee. The two remaining Claude behavior failures are visible in the
report and require further product work; this PR does not claim all
onboarding scenarios pass.
- The suite checks persisted Paperclip effects. It cannot prove the
absence of arbitrary external effects.
- Historical recordings can miss later journey steps. These remain
incomplete, never passes.
- Native profiles switch runtime after the production onboarding wizard
because it does not yet expose a native option.
- Quality scores are informational and cannot override behavioral
failures.

## Model Used

OpenAI Codex, GPT-6, with reasoning, repository tools, and code
execution. The exact deployed model identifier 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-09-16 14:24:32 -05:00
cceeb0aa66 test(runner): add everyday workflow evaluation harness (#13474)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - The native runner must support project work, delegation, hiring, and
service access.
> - Browser tests exposed lost connection access, rejected helper
events, and stalled recovery.
> - Some eval failures also came from incorrect fixtures and decision
controls.
> - This pull request fixes those paths and adds eight everyday workflow
stories.
> - The tests retain observed failures and verify delivered files
independently.
> - The benefit is repeatable evidence for common user tasks and their
remaining gaps.

## Linked Issues or Issue Description

Related work: #13404 contains earlier workflow fixes. #13300 and #13470
changed the CI contracts used by the harness security tests. Merged
companion:
[paperclip-evals#22](https://github.com/paperclipai/paperclip-evals/pull/22).

**What happened?**

Native ACPX sessions did not receive the assigned connection gateway.
Codex helper events could arrive before their spawn receipt and fail
thread validation. A parent continuation could take a shared workspace
before its child retried. A failed native continuation could leave the
task status without a clear recovery blocker. The eval harness also
confused tool approvals with new connection requests and could reject a
valid delegated download.

**Expected behavior**

Keep assigned gateway access and its approval checks. Verify helper
lineage before accepting helper progress. Let a waiting child proceed
before automatic parent recovery. Preserve a failed task's recovery
ownership. Grade the actual requested workflow and its delivered files.

**Steps to reproduce**

Run the everyday workflow suite with the native Codex and Claude
profiles. Exercise service approval, connection refusal, delegated
project work, and teammate reuse. The commands and case requirements are
in `tests/runner-e2e/EVERYDAY-WORKFLOWS.md`. Use `pnpm
test:runner-recovery` for controlled crash and replacement cases.

## What Changed

- Pass the scoped connection gateway binding through the native ACPX
host and sidecar.
- Recognize Codex helper lineage from parent metadata and spawn
receipts. Verify early helper events with `thread/read`. Keep helper
events separate from root completion authority.
- Guide agents to use persistent hiring, child tasks, dependency
records, and a blocked handoff while waiting for a child.
- Defer automatic parent recovery while a child has an active execution
path in the same shared workspace. Allow parent recovery when the child
needs review.
- Record Blocked status and recovery evidence when a failed native
continuation needs reconciliation, including existing active or
escalated incidents. Preserve their owner and retry budget.
- Add eight browser-driven workflow cases. Use real decision controls,
explicit child feedback delivery, managed hiring credentials, and
independent ZIP checks inside a bounded Docker sandbox. Verify sandbox
availability before task creation. Record screenshot SHA-256 at capture.
- Keep runner crash probes in controlled recovery tests. Preserve the
original failure when cleanup also fails.
- Display missing accounting and replay revisions as unavailable. Align
harness security assertions with the approved CI changes.
- Make the channel-rejection browser fixture bind its file after the
send captures its payload. This prevents live refresh from removing the
file before the simulated race.

## Verification

- Full workspace `pnpm -r typecheck` passed after merging current
master.
- Runner E2E typecheck passed. Harness unit tests passed: 216/216.
- Wake-queue database tests passed: 55/55. The two added
existing-incident tests failed before the fix and pass after it.
- Docker artifact calibration passed: 12/12. Host-file and host-loopback
isolation tests failed before the fix and pass after it. Read-only
delivery and output limits are also verified.
- Full `pnpm build` passed. Targeted recovery tests passed: 83/83.
- The channel-rejection browser test passed five consecutive runs after
fixing the fixture race found in CI.
- Local general-server (12,351 tests), UI (6,250), CLI (485), and
workspace package groups passed. The monolithic run stopped at an
unchanged lock-heartbeat fixture race; the isolated workspace group
passed on rerun (shared: 747/747). A separate local serialized run
passed 97 files before two socket errors in the unchanged issue-list
route suite; that suite passed 15/15 on isolated rerun. These local full
commands did not finish uninterrupted; the complete CI matrix below
covers the remaining suites.
- Final head `0fb293733fe307be7e6667ae8f1364077d0c6455`: **34 successful
checks, 2 expected skips**, including every server/workspace shard,
browser shard, native runner verification, build, and typecheck. [Final
CI
run](https://github.com/paperclipai/paperclip/actions/runs/34989136700).
- Greptile reviewed this exact head at **5/5**; all review threads are
resolved. Both Superagent security checks are successful.
- ACPX credential-boundary tests passed: 118/118. Superagent accepted
the runner/sidecar versus provider-environment trace and cleared its
finding.
- The latest paid local campaign on source
`f6a2fdf7ac2af859826a2ae627ff4125a5478529` passed 22/24 cases: Sol 8/8,
Claude 7/8, Mini 7/8. These results predate the merge with current
master.
- The two remaining failures are in `hire-reuse`: Claude exceeded the
attempt deadline during final review; Mini made invalid deliverable tool
calls and remained Blocked.
- Six Daytona cases were not run because the matching immutable runner
image was unavailable. This PR does not claim new remote model results.

## Risks

The changes affect connection admission, helper identity, and recovery
scheduling. Assigned gateway grants and user approval still govern
service calls. The workspace admission gate still exists; the broader
folder-sync design is separate work. Provider behavior can still cause
the two recorded hiring failures. No database migration is required.
Paid cases are opt-in and have bounded attempt deadlines. Project
stories now require Docker and the documented pinned Python image on the
harness host.

## Model Used

OpenAI `gpt-6-astra` performed implementation, diagnosis, and
substantive review. OpenAI `gpt-5.6-luna` assisted with verification, PR
preparation, and review tracking. Both used repository tools and code
execution. Context-window sizes were not recorded.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass (focused checks and
isolated reruns; full-run limitations are 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: OpenAI GPT-5.6 Luna <noreply@openai.com>
Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-09-15 11:04:16 -05:00
DottaandPaperclip 78ce96a48b fix(runner): restore native Claude context and read permissions (#13422)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - The native runner supplies each agent with instructions, assigned
skills, and tools.
> - Native Claude lost its skill snapshot before provider launch. It
also changed exact model IDs to aliases.
> - The read permission mode denied ordinary Paperclip reads because
this runner has no interactive approval handler.
> - This pull request restores the missing context and permits only
assigned tools that Paperclip defines as reads.
> - Other requests that need approval stop with a clear action for the
operator. They do not retry automatically.
> - Agents can complete read tasks. Users can see why a restricted task
stopped.

## Linked Issues or Issue Description

**What happened?**

Native Claude could not find assigned skills. The ACP layer could
replace an exact model ID with an alias and then fail identity
verification. The default `approve-reads` mode denied Paperclip read
tools. A denied write showed a generic transport failure.

The tool descriptions also called live operations “mock” operations. The
completion prompt said to call a completion tool once, although the
protocol can reject a claim and require a corrected call.

**Expected behavior**

Load assigned skills before launch. Keep the selected model ID. Allow
assigned Paperclip reads. Stop an operation that needs approval with
clear instructions when no approval handler exists.

**Steps to reproduce**

1. Configure a native Paperclip Runner agent with ACPX Claude and an
exact model ID.
2. Assign a skill and ask the agent to use it.
3. Select the read permission mode and ask the agent to read task
context and list documents.
4. Ask the agent to write a document. Check the task state and recovery
message.

**Paperclip version or commit**

Reproduced from `d351e08deee1b49d3467a950d1a3f01131943441`.

**Deployment mode**

Local native runner with real Claude, Rust runnerd, the Paperclip
server, and embedded PostgreSQL.

Related: #13196 fixed remote skill staging in the legacy `claude_local`
adapter. The native runner uses a separate path, which this pull request
fixes.

## What Changed

- Carry the runtime context through Rust and the ACPX sidecar. Load
assigned Claude skills after the provider lifetime lease is held.
Refresh the files on each open.
- Write the exact requested model ID into the isolated Claude settings.
- Grant exact MCP permissions for the intersection of assigned tools and
Paperclip's read catalog. Provider hints cannot grant access. Existing
task-control permissions stay in place.
- Stop requests that need an unavailable approval handler. Preserve the
typed error through the server. Show “Approval required” on the task and
require operator action without automatic retry.
- Label the setting “Allow Paperclip reads.” Remove “mock” from live
tool descriptions and regenerate the contracts.
- Change one completion-prompt sentence to require one accepted result.
Add regression tests and update the runner documentation.

## Verification

- Red/green regression tests cover read admission, unavailable approval
handling, server recovery, and the task error message.
- A real Claude read trial failed before the fix and completed after it:
[red
trace](https://www.braintrust.dev/app/Paperclip/object?object_type=project_logs&object_id=fda74078-b00d-495a-90d3-ea1be019d71b&id=95e6a326e24437f1),
[green
trace](https://www.braintrust.dev/app/Paperclip/object?object_type=project_logs&object_id=fda74078-b00d-495a-90d3-ea1be019d71b&id=85a1f347db5604d1).
- Full browser tests used real Claude and the production tool authority.
Reads completed. A write stopped with “Approval required.” No document
was created and no automatic retry was scheduled. All nine checks
passed: [events and
screenshots](https://www.braintrust.dev/app/Paperclip/object?object_type=project_logs&object_id=fda74078-b00d-495a-90d3-ea1be019d71b&id=1c4ff10be0d779cc).
- A separate full browser test assigned a skill, invoked it, and
completed with a marker absent from the task prompt: [skill
evidence](https://www.braintrust.dev/app/Paperclip/object?object_type=project_logs&object_id=fda74078-b00d-495a-90d3-ea1be019d71b&id=ba5fbcb29a60be52).
- Post-rebase checks passed: 128 targeted runner tests, 46 Rust tests,
27 sidecar/protocol contract tests, `pnpm -r typecheck`, and `pnpm
build`. The server/UI red-green checks and `pnpm check:token-gates` also
passed. The full suite passed in CI, including all general and
serialized test shards, all three browser shards, and runner
`check:all`. The duplicate unsharded local full-suite run was stopped
after CI passed.

Braintrust links require project access. The traces contain
provider/runner events and app outcomes. They do not contain raw model
HTTP requests.

## Risks

- `approve-reads` now allows assigned Paperclip reads. Other operations
that need approval stop the turn. Users must review the operation and
change permissions before retrying.
- The Claude settings depend on the pinned ACP and SDK behavior.
Automated tests and real Claude trials cover this boundary.
- The native Codex path is unchanged. The ACPX Codex fallback shares the
clearer approval failure handling.
- Local execution was tested end to end. Remote execution was not run.
This change has no database migration.

## Model Used

OpenAI GPT-6 through Codex. The agent used reasoning, code execution,
and browser tools. The exact deployment ID and context-window size were
not exposed in the session. Live acceptance tests used
`claude-sonnet-5`.

## 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-14 10:56:24 -05:00
DottaandPaperclip f2c5e54dca fix(runner): preserve handoff work and publish requested files (#13355)
## Thinking Path

> - Paperclip lets people manage AI agents and their tasks.
> - A task keeps its instructions, progress, and files when its assigned
agent changes.
> - The replacement runner lost the interrupted run's context and could
overwrite an existing draft.
> - A saved message also stayed attached to the former agent and could
reopen the task after the replacement finished.
> - File tasks could report Done with only a local path that the user
could not open.
> - This pull request transfers handoff context and saved messages, and
makes requested files accessible through the existing attachment
contract.
> - Users can change agents and collect completed work without repeating
instructions or confirming bookkeeping.

## Linked Issues or Issue Description

Refs #13338. Builds on merged #13354 for queue admission and #13353 for
remote workspace retry. #10123 concerns restricted recovery-model
escalation; this change instead covers ordinary native handoff and file
completion.

**What happened?**

Codex wrote a draft before a user assigned the task to Claude. The
replacement lacked continuation context and replaced the draft. A queued
user message could later restart the former agent and reopen the
completed task. Separately, a runner could finish a requested file but
return only a machine-local path. Remote native runs had no bound file
publication tool.

**Expected behavior**

The replacement reads and preserves existing work, receives saved
messages once, and keeps each message's author. The former agent stays
stopped. A requested file has a working attachment or accessible work
product before Done. Text-only tasks do not require attachments.

**Steps to reproduce**

1. Ask Codex to save three newsletter names and then wait.
2. Queue an instruction to keep those names and expand the draft.
3. Use Interrupt and assign to select Claude.
4. Verify the original names survive, the result has a working download,
and only the source and replacement runs exist.
5. Ask either provider for a Markdown checklist and open the file from
its completed response.

## What Changed

- Carry the exact same-task interrupted run's summary, semantic
receipts, and history into handoff context. Tell the replacement to
inspect existing files before editing.
- Adopt saved ordinary task comments into the successor's receipt under
the task lock. Preserve authors and separate mention, chat, and
interaction contracts.
- Prevent a former-assignee comment wake from reopening a completed task
or starting a stale execution.
- Reject workspace-only, fabricated, and cross-task file completion
references with actionable runner feedback. New file output also needs a
matching current-run publication receipt and asset filename/size/hash,
or an accessible work product registered by the current run. Prior
output can remain context alongside a current file, or be verified and
re-registered internally. Authorized chat attachment reuse retains its
verified current-run clone receipt; older receipt shapes require an
intact matching source.
- Bind remote file reads to the active environment runner and reuse the
existing attachment and work-product publication path.
- Enforce workspace confinement, regular single-link files, stable
identity, a 10 MiB limit, and exact size and SHA-256 checks. Rotate the
native session fingerprint for the updated tool contract.
- Contain rejected remote signals and protocol-failure cleanup,
including logging failures. Preserve the original cleanup rejection for
its owner; a rejected operation never supplies stop acknowledgement or
cleanup proof.
- Allow exactly one maximum-size base64 file through the native SSH
command adapter, preserving a finite output cap.
- Document handoff and accessible file completion rules.

## Verification

- Each observed bug has a failing regression before its fix. Final
post-rebase integration passed 732 tests across 13 files before the
final receipt and signal guards; final affected results are below.
- Publication provenance and compatibility: 8 provenance regressions and
2 compatibility regressions failed before their fixes; the final four
affected suites pass 53 tests, including mixed old/new references and
real authorized chat reuse. Controls cover old attachments and work
products, filename/size/hash/origin mismatch, missing/wrong receipts,
current-run publication, same-run durable proof, internally
re-registering preserved bytes, and no-new-file follow-ups.
- Remote signal rejection: the real Node subprocess previously exited 1
when the production launcher signalled a deleted sandbox. It now stays
alive for both a failed signal and failed logging; all 349 executor
tests pass. The failed signal still provides no termination proof.
- Remote file reader and SSH command boundary: 33 tests passed,
including real Linux descriptor reads and the actual SSH adapter
subprocess output cap (network executable replaced by a deterministic
fixture). Exact 10 MiB bytes pass, one byte beyond the encoded cap
fails.
- Live local Claude and Codex Stop journeys preserve the saved file,
deliver queued instructions once, and reach Done with two total runs.
The handoff journey preserves the original names and download with
exactly two runs. Both local providers deliver exact checklist files
without a completion confirmation.
- Live combined Daytona verification passed: the original failed task's
Retry reused its sandbox; a selected Git subfolder produced an exact
downloadable file; warm and deliberately resumed Claude runs took about
33 seconds. Codex produced a 240-byte download in 33.1 seconds after 134
seconds of contention/backoff. Both cloud downloads retained exact bytes
after the two owned sandboxes were deleted.
- The sandbox-deletion retest identified a separate ignored promise in
protocol-failure cleanup. Two real Node subprocess regressions failed
under fatal unhandled-rejection policy before the fix; all 36 protocol,
lifecycle, and integrity tests now pass. The original close promise
still rejects to its owning runtime. The final live retest passed: a
normal Claude Daytona task completed in 132.352 seconds, then its
sandbox was deleted. Thirteen samples over 361 seconds confirmed the
same controller stayed healthy, the task stayed Done with unchanged run
IDs, and its attachment retained exact bytes. The post-deletion browser
download passed with zero page errors; all five owned sandboxes are
confirmed absent.
- Full repository typecheck and build passed on final commit
`de64d16f1`. Final-head Greptile is 5/5 with no unresolved threads.
[Final-head
CI](https://github.com/paperclipai/paperclip/actions/runs/34736623758)
passed: 32 successful checks and two conditional skips. The earlier
mixed-source full local test invocation was deliberately stopped before
rebase, so no pristine green full local aggregate is claimed. Its known
failures passed in later affected suites.

## Risks

- Handoff may adopt only ordinary comments from its validated former
owner. Other delivery contracts must remain independent.
- File verification fails closed if a remote file changes during
reading. The runner must retry publication or explain a blocker.
- The updated session fingerprint starts a fresh provider process where
needed to install the new tool contract.
- No schema migration or historical status reconciliation is included.

## Model Used

OpenAI `gpt-6-astra` through Codex, with reasoning, code execution,
browser testing, and tool use. The context-window size is not exposed in
this task.

## 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-13 08:41:20 -05:00
DottaandPaperclip 422287eecd fix: preserve runner recovery, warm sessions, and task outcomes (#13338)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - The native runner connects task messages, provider execution, and
task outcomes.
> - First-time user tests exposed gaps in recovery, completion
permissions, message delivery, and Stop behavior.
> - These gaps left usable output hidden, completed work waiting for
bookkeeping, or safe work unable to continue.
> - This pull request fixes the shared lifecycle and receipt paths while
preserving process ownership and action checks.
> - Users can continue work with accurate task state and durable
messages.

## Linked Issues or Issue Description

**What happened?**

A stopped local Codex execution could remain blocked even after its
processes had stopped and its complete transcript proved that no
external action needed replay. Claude under Conservative permissions
could fail to call task completion tools. Recovery could reuse an
assistant item ID and overwrite prior output. A delivered comment could
remain marked uncertain after navigation. Stop could look like Pause or
a new recovery incident. Workspace contention could look like
cancellation. A direct reply reopening Done could enter a clarification
loop.

**Expected behavior**

Recover automatically only with verified termination and complete action
receipts. Preserve answers and messages. Keep task completion available
under Conservative permissions without broad tool access. Show crashes
as Blocked, actual human decisions as In Review, and ordinary workspace
contention as waiting. Stop the current response and allow a new
direction.

**Steps to reproduce**

1. Create ordinary response tasks with local Codex and Claude Code, then
send follow-up messages through the task composer.
2. Interrupt a disposable local Codex runner during text-only work.
Verify automatic continuation and retained output.
3. Stop a response, send a new request, answer a clarification, and
reopen completed work with another message.
4. Navigate or reload while a comment submission is pending. Confirm the
exact persisted request receipt settles it without removing newer draft
text.
5. Run two tasks in a shared Daytona workspace. Confirm waiting does not
appear as failure.

**Paperclip version or commit**

Initial acceptance baseline: `c9021c6721f91e2c74bd9fee9d3fd41c999d17b7`.
Current integration base: `6cef9743c`. Both operator-interruption and
workspace-waiting guards are preserved; native restart and legacy
permission rules remain documented.

**Deployment mode**

An isolated source-built test-drive instance, with real local Codex and
Claude Code providers and disposable Daytona environments.

Related work: #13314, #13316, #13327, #13344, #13239, #13254, #13163.
This PR addresses additional failures from ordinary task journeys,
including controller restart handoff and repeated warm sandbox setup.
Historical task status reconciliation is excluded.

## What Changed

- Persist runner ownership immediately at spawn and resume an explicitly
adopted runner even when the controller crashed before the first driver
checkpoint. Detach the controller safely across graceful restarts,
including session startup. Prevent an old finalizer from suspending or
signaling an adopted runner. Checkpoint idle warm sessions before
shutdown. Preserve the same run and queued follow-up messages.
- Scope saved legacy queue successor checks to the queue owner while
preserving ordinary task locks, operator identity, assignment gates, and
exactly-once delivery.
- Preserve managed Codex credential files when an old session is
detached for restart; normal owned cleanup still copies refreshed auth
back and removes the scoped copy.
- Reuse the bound warm shared sandbox and fully verify an existing
staged provider pack before using it. This avoids repeated uploads when
the pack is already valid.
- Add a narrow local Codex replacement path with stopped-process proof,
a closed transcript inventory, exact completion receipts, and
fresh-session lineage. Preserve no-replay holds when evidence is
incomplete. Recovery may clear only the same run's recorded Blocked
status version; manual re-blocking and dependency changes invalidate
that receipt, while queued comments do not. Later blocks stop scheduled,
queued, and final dispatch; queued/final checks re-read dependencies
even when the task status stays In Progress.
- Permit only task delivery and human-input tools through the isolated
Claude runner's exact task bridge.
- Scope assistant item identity to the provider turn and ignore only
authority-free Codex skill-change notifications during startup.
- Reconcile composer submissions by client request ID across response
loss, navigation, and reload. Retain text typed during delivery.
- Keep acknowledged run-only Stop neutral and show workspace contention
as waiting. Project exhausted native failures as Blocked.
- Restore the guarded task-page retry action for failed legacy runs,
including the server-supported explicit new-attempt path for stopped
conversation adapters. Preserve native/process recovery holds and avoid
promising Retry while a decision or execution gate hides it.
- Refresh delivered artifacts and handle direct user replies that reopen
completed work without a clarification loop.
- Check the embedded PostgreSQL PID, data directory, and actual port
before connecting or migrating.
- Document accepted behavior and add focused regressions at lifecycle,
route, transcript, and UI boundaries.

## Verification

- Final head `fece606ac2` passes the complete GitHub CI matrix: **34
green checks, two expected Storybook skips, no failures or pending
checks**, including `ci / verify`, `ci / e2e`, full runner verification,
typecheck, build, every server/workspace shard, and all browser shards.
[CI
run](https://github.com/paperclipai/paperclip/actions/runs/34727183287).
Greptile is **5/5 with no open findings**. The final two commits only
refine test fixtures; both affected suites pass 24/24 locally and in CI,
with server typecheck green.
- Complete local Vitest coverage uses the canonical groups/shards: all
635 general server suites, all 145 serialized suites, and all workspace
packages. The aggregate began on `0a8001c18` while the final queue fix
arrived: 23,903 passed, five failed, 87 skipped. The five
port/socket/timing failures passed unchanged in follow-ups (60 tests in
the exposure/file suites and 412 tests covering the serialized failures
and unrun tails). The final queue/operator-identity suites separately
passed 52/52. This is aggregate coverage plus explicit reruns, not a
pristine single-command final-head run.
- After integration with current master,
queue/operator-identity/continuation suites passed 162/162 and affected
UI suites passed 140/140. ACP Stop/continuation and legacy
task/Inbox/message browser suites passed 9/9, including both task
recovery Retry and thread Try again, automatic saved-message delivery,
exactly one new run, Done, and retained output after reload. The default
process Stop/Pause/Resume browser case passed (the native-provider case
is opt-in and skipped by default). The complete Board attachment/receipt
browser suite passed 11/11 on a disposable instance, covering both
composers, exact receipts after lost responses, no replay, bound
attachments, and newer drafts after reload.
- Blocking-intent regressions cover pre-existing Blocked, a mismatched
run/cause, an explicit manual re-block, changed dependencies, a queued
comment after failure, and a block arriving between scheduling and
provider dispatch. The negative cases reproduced before the fix. All 478
affected executor/recovery/dispatch tests passed; both database suites
ran separately after availability-probe skips in the first combined
command. The final late-dependency check passed all 143 affected
recovery/dispatch tests (zero skips) after two new negative cases
reproduced the bug.
- Focused runtime regressions cover awaited runner ownership
publication, authenticated adoption before the first checkpoint,
old-finalizer detachment, idle and busy warm-session shutdown, rejected
checkpoint propagation, provider-pack verification, and managed-Codex
credential preservation. Four managed credential detachment cases
reproduced the bug before the fix; normal owned cleanup still succeeds
exactly once.
- Live local Claude: SIGKILL 2.6 seconds into startup recovered the same
run automatically in 53 seconds, then a normal follow-up completed in 24
seconds. SIGTERM 2.5 seconds into startup preserved the same run (54
seconds) and its queued follow-up (21 seconds). Answers remained visible
and the task reached Done.
- Live Claude Daytona: a warm follow-up retained its sandbox and fell
from 121 seconds to 44 seconds. A separate cold turn took 127 seconds;
after controller shutdown and checkpointing, its follow-up completed in
33 seconds with the same sandbox, workspace, native session, and runner.
Both answers remained visible and the task was Done.
- Other live journeys covered task completion and follow-up with local
and Daytona Codex, local Codex crash recovery, Stop then new direction,
clarification response, live artifact refresh, and shared-workspace
waiting.
- Validation limits: the opt-in native composer Stop/Pause→subtree
Resume fixture exposes terminal/result ordering and subtree-cancellation
attribution bugs that can leave a child task blocked; that new finding
is assigned to a separate follow-up and is not claimed fixed here.
Default CI skips this optional native-provider fixture. Managed-Codex
credential handoff and the queue-agent integration use automated
regression evidence. Cold custom provider-pack uploads still add startup
latency.

## Risks

- Automatic replacement remains deliberately narrow: local Codex,
verified stopped identities, unchanged retained state, and a complete
text/completion-only turn. Unknown actions, partial history, or changed
ownership remain blocked.
- Claude completion permission handling changes an upstream package
patch. The exact isolated task bridge must remain pinned; unrelated
tools keep their existing permissions.
- New task failure projection changes user-visible status. No historical
status backfill or database migration is included.
- This is a broad lifecycle fix across server and UI. Live proof covers
graceful local Claude restart during startup and idle Claude Daytona
session recovery across controller shutdown. Live abrupt SIGKILL during
local Claude startup also recovered the same run. Unknown ownership or
missing action evidence still blocks reuse. Cold custom provider-pack
uploads still add startup latency; this change avoids unnecessary repeat
uploads.

## Model Used

OpenAI GPT-6 (Codex), with reasoning, code execution, browser
automation, and tool use. The exact hosted model ID and context window
are not exposed in this task.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-09-12 19:41:15 -05:00
DottaandPaperclip df984cbc2c fix: dispatch queued legacy messages with operator identity and task permissions (#13315)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Task conversations save messages that arrive during an active turn.
> - Legacy adapters deliver these messages in a later turn.
> - A run can stop before the saved queue is delivered.
> - The Interrupt button previously required an active run, so it could
not release this queue.
> - This pull request lets a board operator send the saved queue after
the run stops and retries queues missed during finalization.
> - Manual dispatch must use the clicking operator and must not require
permission to create agents.
> - The task can continue without a duplicate message or a second
execution owner.

## Linked Issues or Issue Description

**What happened?**

A legacy task retained a queued message after its run stopped. Interrupt
was disabled because the queue had no active target. Finalization and
deferred message admission can also leave a queue without a successor.

**Expected behavior**

Interrupt sends the saved messages when no runner is active. Messages
that arrive during normal completion are delivered automatically. An
uncertain previous execution still requires proof that its process or
sandbox stopped.

**Steps to reproduce**

1. Queue a user message during a legacy conversation turn.
2. Let the turn stop or simulate a server restart before queue
promotion.
3. Open the task with a deferred queue and no active run.
4. Try Interrupt. Before this change, the button is disabled.

**Paperclip version or commit**

Reproduced against `8f40b4ad4`.

**Deployment mode**

Legacy conversation adapter. The same persisted queue state is covered
with an isolated PostgreSQL fixture.

Related public work: #13275 adds active legacy interruption. #13291
addresses automatic sandbox conversation recovery. This change handles
explicit saved-queue delivery and late queue promotion.

## What Changed

- Accept a null Interrupt target while retaining queue identity,
revision, company, and assignee checks.
- Save the operator's request on the existing queue. Reuse normal
admission after verified stop, including older messages, different
authors, and queues whose original wake came from the system.
- Strip interruption authority from caller-supplied wake payloads. Only
the board queue route can persist that authority.
- Retry durable interruption requests after restart and deferred queues
after legacy cleanup.
- Let an explicit Interrupt retry cleanup for its stopped run, including
old ephemeral leases that recorded success without a provider stop
receipt. Preserve retained resources, other lease owners, and the
automatic retry limit.
- Preserve the server's waiting explanation when normalizing and
combining queue entries.
- Revalidate the consumed board queue receipt at dispatch so a different
message author does not cause setup failure.
- Use the Interrupt user's execution identity for the new run. Preserve
original message authors. Validate the receipt independently at startup
and inherit the resulting identity on retry.
- Persist authenticated board authority for ordinary manual wakes too.
Adopting someone else's queued messages cannot switch a manual run to
that author's permissions. Strip caller-supplied authority markers and
retain private conversation ownership checks.
- Keep the clicking user when a manual wake is merged into an older
deferred receipt. Update its requester and payload in the same
transaction.
- Use the same current-queue/revision API on task details and pipeline
conversations; show Interrupt after a legacy target stops.
- Keep manual wakes out of active runs, including unscoped agent wakes.
They receive their own execution identity; a matching receipt requester
is not sufficient because an exact retry can retain a different
originating identity.
- Authorize both existing-agent wake endpoints with `agent:wake`,
available to active non-viewer company members. Keep `agents:create` for
hiring. Validate the stored task and current assignee before an exact
task retry.
- Reject viewer Interrupt requests before saving intent or stopping
execution. Keep external chat retry authorization and per-action
agent/user permission checks.
- Preserve edits and discards until dispatch. Prevent another queue
promotion when the same agent already has a successor. Keep independent
reviewer recovery available.
- Suppress cancelled/failed run toasts for intentional operator
interruption. Keep ordinary runtime error notices.
- Add UI, route, admission, restart, successor ownership, and toast
regression tests. Document the behavior.
- Reuse the existing socket reservation helper for both
credential-quorum test cases after CI exposed an ambient-port collision.
This changes test preparation only; production credential staging is
still called exactly once.

## Verification

- Failing regression tests reproduced the message-author identity bug
and an operator's `agents:create` rejection before the fixes.
- All 316 focused tests pass across eight route, queue, identity,
authorization, continuation, and responsible-user suites, including the
44-test rerun of queue admission and actual startup after the final
manual-wake restriction. Regressions reproduce cross-user merging both
with and without a task, and same-requester receipt ambiguity. The
cross-company existence guard also passes both tests.
- Startup integration tests reach adapter execution under the clicking
operator and retain that identity through follow-up. Coverage includes
mixed authors, adopted queues, system-origin queues, restarts, forged or
stale receipts, viewers, suspended memberships, changed assignees,
private conversations, and caller-supplied authority markers.
- The earlier queue/cleanup/UI regression suite passed 402 tests. The
final review corrections pass another 180 tests across queue
admission/persistence, real heartbeat startup, UI API, conversation
rendering, and pipeline suites. Regression tests reproduced both review
findings before correction. The final head has a 5/5 review with no
unresolved threads. Full CI passes on `c2002979c`, including every
general and serialized server shard, all browser shards, Paperclip
Runner verification, typecheck, build, canary dry run, and the aggregate
gates.
- Full `pnpm -r typecheck`, `pnpm build`, and UI token gates pass after
the final application changes. CI identified an outdated task-page API
mock after the shared helper extraction; the fixture now exercises the
real helper, and all 131 task-page/API tests pass. The final application
build passes with the additional manual-wake restriction.
- CI exposed a pre-existing port collision in the Codex
credential-quorum fixture. It reproduced locally; both listener cases
now use the existing bounded reservation helper. All 41 credential tests
pass on rerun. One intervening local run hit a separate ambient bind
collision in the two-occupied-port case.
- The full local `pnpm test:run` attempt was stopped after host
contention caused focused-suite timeouts. The affected focused tests
passed on rerun. An expiring trace fixture and a missing
private-conversation state were corrected. The successful full CI run is
the complete-suite verification.
- Hosted Interrupt previously cleared the original queue and produced
exactly one successor with neutral interruption feedback. It exposed the
dispatch authorization defect. Retry on that earlier build was rejected
for missing `agents:create` before creating another run.
- Deployed the final application build (`38257f391`) to the scoped
hosted instance and verified readiness. The latest PR commit changes
only the credential test fixture; application code matches that
deployment. A live Retry by the same operator without `agents:create`
created one successor attributed to that operator, passing the former
dispatch permission gate. Startup then stopped at
`configuration_incomplete` because that operator has not configured
their required personal Claude Code OAuth secret; the post-deployment
run page confirms the operator identity and no provider work started,
and the My secrets UI still shows the token as not set. Provider
execution remains unverified pending that credential. No permission
grants or credentials were changed.

## Risks

Queue admission and finalization can race. The task lock, durable queue
receipt, current comment IDs, and successor guard prevent duplicate
dispatch. Process and lease stop checks, task pauses, approvals,
ownership, and budgets remain in force. The API change only allows null
on legacy Interrupt; native steering still requires an active run. No
schema migration is required. Active non-viewer board members can now
invoke existing agents without agent-creation permission. Agent
self-invocation rules, raw provider-trace admin access, task retry
scope, external chat authorization, and action-specific user/agent
permissions remain enforced.

## Model Used

OpenAI GPT-6 through Codex. The session does not expose an exact backend
model ID or context-window size. Used reasoning, repository search, code
execution, tests, and browser 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)
- [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
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-09-12 17:11:30 -05:00
DottaandPaperclip c9021c6721 fix: require explicit native completion reviews (#13314)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Native runs report their outcome through paperclip_finish.
> - The server previously turned incomplete reports into human approval
requests.
> - Those requests could block a later successful run, even when no
person had requested review.
> - This pull request creates review cards only for explicit attention
requests and withdraws proven old fallback cards.
> - Agents receive useful completion feedback, while explicit approval
gates and task state protections remain in force.

## Linked Issues or Issue Description

Related: #13266 removed reviews caused by policy upgrades. This change
removes the separate completion fallback.

**What happened?**

An agent reported needs_review while waiting for checks without
requesting a human decision. Paperclip created a generic Native
completion review. A later successful report could not complete the task
because that old card remained pending.

**Expected behavior**

Ordinary low-risk work completes after a valid done report, a successful
run, and workspace finalization. Incomplete work stays with the agent.
Explicit approval requests remain visible and must be resolved.

**Steps to reproduce**

1. Complete a native run with needs_review and no attention requests.
2. Continue the task and submit a successful done report.
3. Observe that the old implementation leaves the task in review behind
a generic confirmation card.

## What Changed

- Require explicit attention requests to create native review cards.
Route each request independently and preserve pending or declined
decisions.
- Withdraw only pending system cards with matching old decision,
assessment, effect, contract, and prompt provenance. Preserve history
and explicit or answered requests.
- Reassess an affected current result without overwriting later task
edits, runs, contracts, or workspace failures.
- Return pending approval links and required actions through the
completion tool. Reject contradictory done reports and empty review
requests before accepting a result.
- Allow one corrective continuation for incomplete results, then expose
a recovery action.
- Update status fixtures, database regressions, runner tests, and the
completion contract documentation.

## Verification

- `pnpm -r typecheck` passed after merging current master.
- `pnpm build` passed after merging current master.
- The combined branch passed 89 completion and Agent Chat tests. Other
targeted tests passed: 170 external-chat and reconciliation tests; 50
runner-resume and control-plane tests; 13 arbiter tests; 7 chat delivery
tests; 21 runner completion and runtime-context tests.
- The full local test attempt exposed old review fixtures and a missing
fake-provider binary. The fixtures are fixed and the helper is built.
All affected suites pass in fresh reruns. The timing-sensitive Discord
test also passed on rerun.
- All latest-head CI checks passed, including build, typecheck, general
and serialized tests, runner verification, browser tests, and canary dry
run. Greptile is 5/5 with zero unresolved comments.

## Risks

- Cleanup changes existing pending cards. It requires exact system
provenance and only applies to low-risk agent-claim contracts. It does
not delete history or dismiss explicit requests.
- Status still commits after the turn and workspace finalization.
Completion feedback reports current constraints and does not claim an
early status commit.
- Incomplete reports now request a bounded corrective run instead of an
automatic approval. Repeated failures expose recovery.

## Model Used

OpenAI Codex, GPT-6, with repository inspection, code execution, and
test tools. The exact deployment identifier 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-09-12 13:00:04 -05:00
DottaandPaperclip ab15aff390 feat: add experimental persistent agent chat (#13284)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Conversations must use the same tasks, controls, and execution
history.
> - Users need an ongoing chat with an agent without managing task
properties.
> - Agents should clarify and plan work, then hand execution to assigned
project tasks.
> - This pull request combines the reviewed Agent Chat stack for one
squash merge.
> - The benefit is persistent conversation with normal task governance
and shared UI.

## Linked Issues or Issue Description

**Subsystem affected**

Task lifecycle, agent runtime tools, shared task UI, and browser/paid
runner tests.

**Problem or motivation**

Users need one persistent conversation with each agent. A separate chat
store or renderer would duplicate task behavior and bypass existing
controls.

**Proposed solution**

Use a task-backed chat per company, user, and agent. Reuse the task
composer and transcript. Clarify and plan in chat, then create assigned
project tasks with the relevant plan. Keep Agent Chat behind its own
disabled-by-default experimental setting.

**Roadmap alignment**

This implements the task-backed direction in [CEO
Chat](https://github.com/paperclipai/paperclip/blob/master/ROADMAP.md#-ceo-chat).
Related proposals: #2504 and #9693. Related request: #7981. The
maintainer requested one squash merge of the complete stack.

Consolidates the reviewed runtime
[#13281](https://github.com/paperclipai/paperclip/pull/13281), backend
[#13282](https://github.com/paperclipai/paperclip/pull/13282), and UI
[#13283](https://github.com/paperclipai/paperclip/pull/13283) layers
with this PR's E2E coverage. All four layers passed CI and received
Greptile 5/5 before consolidation. This PR targets master and includes
the complete feature.

## What Changed

- Add personal canonical chat tasks with ordinary company visibility,
immutable identity, idempotent first sends, and an idle waiting state.
- Process `/new` in queue order. Preserve history, release a chat pause,
and fence old provider context and delayed writes.
- Keep chat lifecycle rules across recovery, finalization, assignment,
task lists, and rollups.
- Support research and plan revision in chat. Hand plans to ordinary
assigned project tasks before execution starts. Reject new chat
subtasks.
- Add repository-aware project creation and discovery tools, including
multiple repository IDs and GitHub URLs, authorization, idempotency, and
durable project-created cards.
- Reuse task UI components for chat, with starred/recent agent
navigation and a separate `enableAgentChat` experimental flag.
- Add deterministic browser tests and 24 paid chat cells across four
Codex/Claude profiles, with validated reports and screenshots.
- Integrate current master recovery, controller lease, queued-message,
and task UI changes. Gate chat interruption and deferred promotion on
ownership/feature policy. Guarantee lease renewal and active controls
are stopped even if teardown fails.
- Preserve master's migration 0273 and generate chat migration 0274 with
idempotent replay for development databases.

## Verification

- Prior exact heads of all four PRs passed Linux CI, including build,
typecheck, general/serialized tests, and browser E2E. Each had Greptile
5/5 and no unresolved findings.
- Integrated local verification passed: full repository typecheck and
production build, Storybook build, token gates, 340 focused UI tests,
all 20 deterministic chat browser tests, two migration replay tests, 88
focused chat/queue/native/controller tests, and provider/session
regressions including real lease expiry. These include the three
lifecycle regressions for the final admission/teardown fixes; server
typecheck also passes. Current head
`1268eda16cc2af892055917e7292f068820be135` has Greptile 5/5 with no
unresolved findings and passing security scans. All final-head CI gates
passed: build, full Runner verification, typecheck/release registry,
canary, all general/serialized test shards, and all browser E2E shards
([CI
run](https://github.com/paperclipai/paperclip/actions/runs/34696739927)).
Local PostgreSQL startup contention required serialized retries; skipped
fixtures do not count as passing coverage.
- The earlier paid campaign passed all 24 chat cells and retained 32
screenshots:
[report](https://d1p6rlowie26tp.cloudfront.net/runner-e2e/campaigns/gha-34648511170-1/index.html?report=agent-chat#suite-agent-chat).
It tested `abacbdfd2f660709ec37312cdb758284c8399d04`; it is prior
evidence, not a paid run of this integrated head.
- Manual check: enable Agent Chat in Experimental settings, open an
agent, clarify and revise a plan, then hand off to an assigned project
task. Stop a reply, send `/new`, and verify fresh context with retained
history. Disable the setting and verify agent shortcuts/new chat turns
are blocked.

## Risks

- Queue/session integration can affect retries and delayed writes. Tests
cover ownership, cancellation, reset boundaries, idle recovery, and
ordinary task behavior.
- Migration 0274 adds conversation fields and constraints. Replay is
idempotent and preserves existing development chat history.
- This combines the previously reviewed stack at the maintainer's
request. Agent Chat remains off by default and is separate from
Conference Room.

## Model Used

OpenAI Codex, GPT-6 Astra (`gpt-6-astra`), with reasoning, code
execution, browser tools, and parallel review. The exact context-window
size is not exposed in this session. Codex and Claude also ran as test
subjects in the linked paid campaign.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-09-12 08:56:04 -05:00
Devin FoleyandPaperclip 5cc7784986 test: remove cold executable reads from runner integrity deadlines (#13301)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Native runner protocol tests verify that invalid authenticated input
fails closed.
> - Cloud readiness requires those tests to pass before a source commit
can deploy.
> - Two test fixtures hash the host Node executable twice even though
its process launcher is synthetic.
> - Cold reads of a large Linux executable consume time unrelated to
protocol failure handling.
> - This PR gives both synthetic runner fixtures tiny real artifacts and
keeps their existing deadlines.
> - Real authentication, encrypted frames, and request and notification
failures remain covered.

## Linked Issues or Issue Description

**What happened?**
Cloud readiness repeatedly failed in `DurablePrpControlPlane > promptly
fails the real transport request and notification paths on authenticated
bad semantic input (throwing observer: false)` with `Test timed out in
5000ms`. The image built, but the failed source check prevented
deployment. See runs
[34656885170](https://github.com/paperclipai/paperclip/actions/runs/34656885170)
and
[34657111560](https://github.com/paperclipai/paperclip/actions/runs/34657111560).

The first case took 5.6–11.4 seconds; the following case took about 0.4
seconds. The original test reads and hashes `process.execPath` once
itself and once through the real transport. The Node executable is
122,678,944 bytes in the local Linux Node 24 container, versus 68,672
bytes on the development Mac. Instrumented Mac runs pass; cold
executable reads are a likely cause of the CI-only timeout.

**Expected behavior**
The deadline should measure real protocol rejection and consumer
failure, without reading a large unrelated executable as test fixture
data.

**Steps to reproduce**
1. Run the named test with the real transport and synthetic process
launcher.
2. For a deterministic probe, inject a six-second delay into the first
`readFileSync(process.execPath)` call.
3. The original test exceeds its existing five-second deadline. Both
cases pass after this change because neither reads the host executable.
The probe is temporary instrumentation, not part of this commit.

**Paperclip version or commit**
f12b647ae; the same failure also occurred on a38ccf997 and 9031516a7.

**Deployment mode**
Cloud readiness in GitHub Actions on Linux AWS runners. No duplicate
open PR found after searching runner timeout and durable PRP changes.

## What Changed

- Write a 26-byte synthetic runner artifact inside each existing
temporary test directory.
- Bind both the real authority and test client to that artifact's actual
SHA-256 digest.
- Retain synthetic process launchers, real wire exchange, all observer
and composed-runtime cases, integrity assertions, cleanup, and existing
five- and fifteen-second timeouts.

## Verification

- Passed all 107 tests across
`src/control-plane/durable-prp-control-plane.test.ts` and
`src/drivers/codex/codex-protocol-integrity.test.ts` using the package
Vitest configuration.
- With a temporary six-second host-executable read delay, the original
case times out. Both fixed cases pass in 235 ms combined under the same
fault injection.
- Passed `git diff --check`.
- Full workspace typecheck and build passed. The full local test command
stopped after the general server group: 10,694 tests passed and 15
failed. Thirteen failures involve macOS directory rename permissions in
the skill-cache suites. Two failures involve a missing local AgentMail
skill path. Later groups did not run in that local invocation. The
targeted runner tests passed; all Linux CI test groups passed.
- [Current-head CI run
34661107658](https://github.com/paperclipai/paperclip/actions/runs/34661107658)
passed. All 32 checks are green or intentionally skipped at
`e7053594e647fd8e9b71fc569cab6b7a3e9cd210`. Native runner verification
passed in 15m25s. Greptile is 5/5 on that head, with no unresolved
review findings.

## Risks

Low risk: this changes test fixture data only. The launcher never
executes the file. Artifact hashing and authentication still use real
bytes. Protocol behavior and existing test deadlines do not change. The
current Linux CI run passed both fixtures and the full native runner
verification. Further post-merge runs will test repeatability.

## Model Used

OpenAI GPT-6 through Codex, with reasoning, repository tools, and code
execution. The exact serving model ID and context window are not exposed
by this environment.

## 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 (targeted runner tests;
full local suite limitations are listed 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-09-11 17:39:57 -07:00
Nicky LeachandClaude Sonnet 5 c1b55537ba fix(paperclip-runner): bump claude-agent-acp pin to 0.73.0 (#13162)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - The Claude local adapter can run agent turns through an ACP (Agent
Client Protocol) server, `claude-agent-acp`, instead of the plain CLI
> - Two separate packages each pin their own copy of that dependency:
`packages/adapters/claude-local` (the server-side adapter) and
`packages/paperclip-runner` (which builds the provider pack baked into
every managed sandbox image)
> - `claude-local` moved to `^0.73.0` in #12730, but `paperclip-runner`
was never bumped past `0.70.0` — nothing keeps the two in sync when only
one changes
> - That split means a sandbox image built from `paperclip-runner`'s
provider pack ships a `claude-agent-acp` the server-side adapter was
never actually compatible with
> - This pull request bumps `paperclip-runner`'s pin to `0.73.0`, the
only version that satisfies both packages' declared ranges at once, and
fixes the matching hardcoded version assertion in
`docker/daytona-runner/Dockerfile`
> - The benefit is one consistent, compatible `claude-agent-acp` version
across both the server host and every sandbox image built from this
source, instead of a silent split that only surfaces as a runtime
failure

## Linked Issues or Issue Description

No public issue exists for this specific split; opening directly per
CONTRIBUTING.md path B, following the bug report template fields.

**What happened?**
`packages/paperclip-runner/package.json` pins
`@agentclientprotocol/claude-agent-acp` at an exact `0.70.0`.
`packages/adapters/claude-local/package.json` requires `^0.73.0` (added
in #12730, 2026-09-02). Nobody re-synced `paperclip-runner`'s pin after
that change — the two packages' dependency graphs are independent, so a
bump in one doesn't propagate to the other. `paperclip-runner`'s copy is
what the fleet sandbox image's provider pack actually ships, so every
managed sandbox built from current source carries a `claude-agent-acp`
version the server-side adapter's own declared compatibility range
excludes.

**Expected behavior**
The two packages' `claude-agent-acp` pins should stay within a mutually
compatible range, so a sandbox image built from this source always ships
a version the server-side adapter actually supports.

**Steps to reproduce**
1. Check `packages/adapters/claude-local/package.json`'s
`@agentclientprotocol/claude-agent-acp` range (`^0.73.0`).
2. Check `packages/paperclip-runner/package.json`'s pin for the same
package (`0.70.0` before this PR).
3. Note that `^0.73.0` on a `0.x` version only admits patch releases
(`>=0.73.0 <0.74.0` per semver caret rules), so `0.70.0` falls outside
it.

**Paperclip version or commit**
`master` as of this PR (paperclip-runner still at `0.70.0` prior to this
change; claude-local's `^0.73.0` requirement landed in #12730).

**Deployment mode**
Any deployment that runs `claude_local` agents through the ACP engine
against a sandbox image built from `packages/paperclip-runner`'s
provider pack (managed cloud sandboxes in particular).

Related PRs for context (not duplicates — none of these touch
`paperclip-runner`'s pin):
- #12730 — introduced the `^0.73.0` requirement in `claude-local`
- #11873 — the last time `paperclip-runner`'s pin moved (`0.69.0` →
`0.70.0`)
- #13105 — separately made an unavailable ACP engine a hard failure
instead of a silent CLI fallback, which is what turned this version
split into a visible, run-blocking error rather than a quiet downgrade

## What Changed

- Bump `@agentclientprotocol/claude-agent-acp` from `0.70.0` to `0.73.0`
(exact pin, matching this package's existing pin style for its other
agent-CLI dependencies) in `packages/paperclip-runner/package.json`.
- Update the corresponding hardcoded version assertion (`test
"$(claude-agent-acp --version)" = "0.70.0"`) in
`docker/daytona-runner/Dockerfile` to `0.73.0`, so its own build-time
check stays accurate instead of failing on the next build for an
unrelated reason.
- `pnpm-lock.yaml` is intentionally **not** included —
`pr-trusted.yml`'s `Validate dependency resolution and regenerate stale
lockfile` step already regenerates it for the merge tree and hands it to
downstream `--frozen-lockfile` jobs as an artifact, so a manual lockfile
commit here would just be stale the moment CI runs.

## Verification

- `0.73.0` is a real published version on npm (confirmed via `npm view
@agentclientprotocol/claude-agent-acp versions`), and it's the *only*
version satisfying claude-local's `^0.73.0` range, so this isn't a guess
at compatibility — it's the unique intersection of both packages'
declared ranges.
- `grep -rn "0\.70\.0" docker/ packages/paperclip-runner/package.json`
after this change shows no remaining stale references to the old pin.
- I did not run a full local install/test pass against a hand-updated
lockfile, since regenerating one locally would conflict with leaving
`pnpm-lock.yaml` untouched per the note above; CI's own
lockfile-regeneration step is the intended verification path for a
manifest-only dependency bump like this one.
- Downstream/full verification (does a sandbox image actually built with
this pin work end-to-end) is tracked separately in `paperclip-cloud` —
an unrelated internal-only repo, so not linked here — where a sibling
fix restores the ACP servers to the runtime `PATH` in the fleet sandbox
image itself; both fixes are needed together for a working sandbox, but
this PR is scoped to the version pin alone.

## Risks

- Low risk: single-line dependency version bump plus a matching
test-assertion update, no code changes. `0.73.0` is a patch release
within claude-local's own already-declared-safe range, so there's no
reason to expect it changes behavior tenants depend on.
- The main risk is unknown breaking changes between `claude-agent-acp`
0.70.0 and 0.73.0 that aren't caught by the version-string assertion
alone (that check only confirms the binary reports the right version,
not that its behavior is unchanged). I have not audited that package's
own changelog between those versions.
- `docker/daytona-runner/Dockerfile` is a parallel/reference image (per
its own header comment, meant to stay aligned with the private
`paperclip-cloud/fleet-sandbox-image/Dockerfile`, which is out of scope
here) — this PR does not touch that other Dockerfile.

## Model Used

Claude Sonnet 5 (`claude-sonnet-5`), via Claude Code, with tool use
(file edits, shell/git, `gh` CLI, `npm view` for version verification).
No extended-thinking mode. Standard Claude Code context window.

## 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 — see Verification: a
manifest-only bump with the lockfile intentionally left to CI's own
regeneration step; no local test run applicable
- [x] I have added or updated tests where applicable — version-pin bump
only, no new behavior to test
- [x] I have updated relevant documentation to reflect my changes — none
applicable
- [x] I have considered and documented any risks above
- [x] All Paperclip CI gates are green — pending CI run on this PR
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups —
pending review
- [x] I will address all Greptile and reviewer comments before
requesting merge

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

---------

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-10 11:35:33 -07:00
DottaandPaperclip 889947c238 feat: add experimental native chat connectors (#13038)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - People also ask agents for work in their existing chat tools.
> - Each external conversation needs one task and a current authorized
source.
> - Retries, Stop, and provider failures must not duplicate work or
expose private data.
> - The first chat PR establishes the opt-in provider and data
contracts.
> - This PR adds experimental channel integration and its durable
control plane.
> - Users can request work from connected channels and inspect delivery
in Paperclip.

## Linked Issues or Issue Description

Refs #13100 and #13092. This is the second of exactly two chat PRs.
Foundation #13100 is merged and changed 143 files. Runner prerequisite
#13092 is also merged. This PR changes 400 files against master, below
the 500-file review limit. It contains no wireframe images or HTML
galleries.

## What Changed

- Add native Slack, GitHub, Microsoft Teams, Telegram, and Discord chat
connections. Keep chat disabled unless the operator enables experimental
chat connectors. Preserve the production GitHub tool connection and its
normal setup path.
- Bind each provider bot identity to one immutable Paperclip agent. Bind
each admitted external conversation to one task. Paperclip owns tasks,
runs, permissions, and audit records.
- Add durable admission, per-conversation queues, questions, task
controls, progress, final replies, images, files, and delivery receipts.
Board comments remain internal unless explicitly sent to the channel.
- Check current identity, provider reach, resource access, credentials,
runtime generation, and exact source before provider effects. Keep
private responses private. Never send raw reasoning, private logs,
credentials, or tool arguments.
- Hold uncertain sends for explicit audited resolution. Make Board
Send-to-channel atomic and idempotent. Keep reconnect and setup
credentials in Paperclip secret storage.
- Preserve current native-runner authority across retries, lost
acknowledgements, and recovery. Keep immutable input and completion
contracts separate from newer user input. Receipt reconciliation cannot
launch a provider.
- Reconcile chat close/new ordering and provider-effect lock order.
Audit resource access changes in the same transaction. Submit only the
selected resource from each UI toggle so stale pages cannot undo
unrelated access changes.
- Drain Codex stdout before certifying process exit. Bound the drain
with the existing shutdown grace. Preserve observed terminal authority
without treating an undrained process as successful or reusable.
- Incorporate master `018ca5da` with its ACP Stop, mobile task layout,
runner packaging, and official lock changes. Preserve dedicated
chat-answer continuations in both directions when ordinary queued
comments are adopted after Stop.
- Fence late adapter readiness behind an earlier Stop for the same run.
Preserve verified cleanup for registered adapters. Handle single Stop,
agent pause, duplicate Stops, and failure release without creating a
false cancellation receipt.
- Incorporate master's `6dd48cad4` wake-queue extraction. Preserve exact
failed-chat retry authorization and lineage, retired question-source
suppression, and the block on generic recovery that would discard the
admitted source. Fresh deferred input retains its separate promotion
path.
- Incorporate master `2a05b5ed3` and its queue-admission extraction,
simplified transaction ports, and separate runner CI job. Preserve exact
durable receipts, actor separation, and dedicated-answer isolation
through the new module. A failed receipt insert rolls back the
accompanying deferred-wake merge.

## Verification

Current head: `afe19299d06253cb628eb398e91d1200ea9f412a`, incorporating
master `2a05b5ed3457ea33efd6895520447d1d97fe98d8`. The conflicts are
resolved. This successor fixes two test-harness boundaries exposed by
CI: per-case route-module preparation and actual durable-save completion
before intentional runner termination. Production code and all existing
test/turn deadlines are unchanged. [Exact-head Greptile
review](https://github.com/paperclipai/paperclip/pull/13038#issuecomment-5587250594)
is **5/5**, completed September 10 at 13:20:55 UTC, with no actionable
findings or open review threads. [Fresh exact-head
CI](https://github.com/paperclipai/paperclip/actions/runs/34481724341)
passes **all 24 jobs**, including Build and both required aggregates.
Normal exact-head guarded merge was attempted and rejected by the
remaining branch approval policy: CODEOWNER review is required and no
human approval is present. Normal **squash auto-merge is enabled** as of
September 10 at 13:36:26 UTC. Requested CODEOWNERS have been notified;
no approval bypass or self-approval was used. Earlier-head results below
remain historical evidence, not qualification of this successor.

- Final exact-head Linux evidence: 995/995 chat integration cases; 36/36
agent-skills routes; 35/35 runner live-session cases, including real
process kill/resume; 1948 runner Vitest cases with three existing
benchmark/platform guards; 870/870 API-authority cases; and 104 browser
cases with four existing optional skips. Rust, conformance/replay, full
repository build, typecheck, canary, all server/workspace shards, and
both required aggregates pass with normal CI concurrency. Earlier failed
attempts remain recorded below.

- Latest test-only qualification: 141/141
route/permissions/authentication cases pass in separate cold forks, with
plain server types and independent review clear. The real-runner suite
passes 35/35, with plain runner types and independent review clear. A
controlled premature-save acknowledgement fails as expected; matching
ownership/effect/process evidence, rejected saves, real turn outcome,
test abort, and pre-kill liveness are covered. No local reproduction of
the original CI scheduling failure is claimed. The preceding [CI
run](https://github.com/paperclipai/paperclip/actions/runs/34479680858)
passes 21/24 jobs, including all 995 Linux chat cases and browser
aggregate (104 passed, four existing optional skips); only Build, the
skills serialized shard, and the required verification aggregate fail.
Its exact-head Greptile review was 5/5. Both failed job logs are
retained.

- Final fixture qualification: all eight focused Discord cases and all
995 chat integration cases pass. The exact modal statement/PID is
observed before taking the real connection lock; the test then proves
its actual blocking relationship before mutation. Original SQL
execution, provider behavior, negative assertions, and 1s/15s timeouts
remain unchanged. Independent review is clear and test/production hashes
remain frozen. The preceding [CI
attempt](https://github.com/paperclipai/paperclip/actions/runs/34477184777)
passed 22 jobs, including Build/runner, typecheck, canary, all other
test shards, and browser aggregate (104 passed, four existing optional
skips); the two fixture failures and failed verification aggregate
remain recorded, not relabeled as a pass.

- Current queue-module composition: 308/308 recovery/batching/queue/Stop
tests; 995/995 full chat integration; 89/89 module tests, including real
PostgreSQL receipt-insert rollback; 24/24 workflow/module-boundary
tests; plain server and UI types. All four actual local process/ACP
browser paths pass in 1.4 minutes. Fresh databases, no skips or retries,
stable reviewed source hashes. The initial boundary failure is retained;
its no-op service wrapper was removed without changing recovery context
or weakening the check. An exploratory standalone test-directory
typecheck fails because its new upstream transformation config is not a
standalone typechecking project; standard CI/build does not invoke it,
and no configuration was weakened to suppress those diagnostics.

- The preceding head `e02a63d462ce5d47433b0aeb632bb6fd20aab1ba` passed
[all 24 CI
jobs](https://github.com/paperclipai/paperclip/actions/runs/34436462958)
and exact-head Greptile review at 5/5. Required CODEOWNER review
prevented its normal merge before master advanced again.

- Final extracted-module composition: 307/307 recovery, batching, queue
and Stop-control tests; 995/995 full chat integration; 49/49 module
tests including eight PostgreSQL adapter cases; and 19/19 issue-update
tests. Plain server types pass. All four actual local process/ACP
browser paths pass in 1.3 minutes. Fresh databases, no skips or retries
in these cohorts, frozen source hashes, and independent review clear.

- The preceding head `3e4e1c1c` passes [all PR CI
jobs](https://github.com/paperclipai/paperclip/actions/runs/34415826820),
including Build and required `ci / verify` and `ci / e2e`. Both the
original Rust failure and the previously load-sensitive lineage fixture
pass with unchanged Linux concurrency. Master advanced afterward and
required this reconciliation.
- Final master composition: 448/448 focused UI tests, 186/186 adapter
tests, 24/24 queue/control tests, and 11/11 packaging tests. Plain UI,
server, shared, and adapter types pass. Token gates and diff checks
pass. Independent server and UI reviews are clear.
- Stop-registration regression: both real-service cases fail against
exact `a95` source and pass with the fix. The full corrected
recovery/control suite passes 265/265. Duplicate-owner and failed-Stop
controls also pass. Plain server types pass. The readiness barrier
prevents provider startup without adding an acknowledgment to an already
terminal run.
- Final qualification strengthens terminal-field equality and repeats
both affected cases successfully on a fresh database. All four actual
local process/ACP browser paths pass again in 1.3 minutes, without skips
or retries. The final screenshot shows Cancelled, a paused subtree,
retained input, and no error toast.
- Two new actual-service regressions fail before the merge fix. They
prove that queued-comment adoption could consume a dedicated chat answer
or add unrelated input to that answer. The fixed four-case cohort
passes, including ordinary upstream continuation and adapter Stop
controls. Full recovery passes 257/257. All four actual local
process/ACP Stop browser flows pass in 1.4 minutes, without skips or
retries, on a fresh database.
- The unchanged runner artifact was qualified with 171/171 transport
tests, 870/870 API-authority tests, conformance 1/1, and replay 11/11.
Six controlled reader tests prove the exit/drain repair. Its local
serial Rust workspace passed 546 top-level cases plus two invoked
helpers; the later passing Linux CI supplies default-concurrency
evidence.
- Prior exact-source full chat integration passes 995/995. Settings
regressions cover concurrent stale pages, 501 destinations, pending
state, rejected updates, and explicit retry. These deterministic tests
do not prove live provider behavior.
- Retained failed attempts and their causes are in the [qualification
log](https://github.com/paperclipai/paperclip/blob/afe19299d06253cb628eb398e91d1200ea9f412a/doc/plans/chat-adapters/2026-09-08-chat-queue-and-webhook-repair.md).
The first merge adapter run timed out while macOS slept for 290 seconds.
Its unchanged repeat passed with a temporary sleep guard. No assertion,
deadline, or CI gate was weakened.

Review commands include `pnpm --filter @paperclipai/server exec vitest
run src/__tests__/heartbeat-process-recovery.test.ts
src/__tests__/issue-queued-comments-routes.test.ts` and `pnpm exec
playwright test --config tests/e2e/playwright.config.ts
tests/e2e/acp-stop-continuation.spec.ts`. Database suites require fresh
disposable databases. See the [browser
runbook](https://github.com/paperclipai/paperclip/blob/afe19299d06253cb628eb398e91d1200ea9f412a/doc/plans/chat-adapters/2026-09-04-chat-adapters-browser-e2e-runbook.md)
for provider setup and separate live acceptance steps.

## Risks

- This remains experimental. Deterministic tests and bounded live
evidence do not establish every provider feature, tenant, permission
layout, or media shape. Teams work-tenant qualification is still open.
- Failed and uncertain provider effects remain visible and can require
operator action. A transport receipt does not prove recipient
visibility.
- Native controller and runner artifacts must remain compatible.
Preserve lease ownership, terminal authority, source binding, and
quarantine during future changes.
- Access and audit rows commit together, but activity notifications
remain best-effort. This is not a new durable event outbox.
- The PR operation does not deploy a live server, replace its runner, or
change provider permissions. Remaining live qualification is documented
in the [temporary
handoff](https://github.com/paperclipai/paperclip/blob/afe19299d06253cb628eb398e91d1200ea9f412a/doc/plans/chat-adapters/2026-09-08-open-qualification-followups.md).

## Model Used

OpenAI Codex assisted with implementation, tool execution, testing, and
review. The work records `gpt-6-astra` assistance. The environment does
not report a context-window size. No private reasoning traces are
included.

## 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-10 10:06:45 -05:00
DottaandPaperclip 3b550c80fa fix(codex): correct startup trust, history reads, and resume usage (#13110)
## Thinking Path

> - Paperclip runs Codex locally and in remote sandboxes.
> - The runner must preserve startup configuration and session identity.
> - Missing project trust can disable repository configuration.
> - Full-history requests use deprecated provider fields.
> - Resume usage describes old work and must not become new run usage.
> - This change corrects startup trust, state reads, and usage
classification.

## Linked Issues or Issue Description

**What happened?**

Normal Codex runs could show repository-trust and history-deprecation
warnings.
Resume could report the preceding turn's token snapshot as a late-turn
warning.
The historical last-usage value could also be attributed to the new run.

**Expected behavior**

Trust the server-selected startup root in isolated configuration. Read
lightweight
provider state and paginated evidence. Use historical cumulative usage
as a
baseline without a new charge or user-facing warning.

**Steps to reproduce**

1. Start a native Codex task in a selected repository.
2. Finish the turn and resume the provider thread.
3. Inspect provider notices, history requests, and per-run usage.
4. Repeat startup and cold resume inside a Daytona sandbox.

**Paperclip version or commit**

Codex CLI 0.153.4 is the pinned runtime and reproduced baseline.
Replayed onto master at 6abeb6733. Related authority work: Refs #13092.
This PR retains its startup cleanup and protocol-integrity checks.

**Deployment mode**

Local source checkout and disposable Daytona sandbox.

## What Changed

- Classify the exact historical resume usage event before the generic
stale-turn warning.
- Persist cumulative usage baselines across recovery of the same run.
- Use excludeTurns on resume and lightweight thread reads.
- Page turn metadata and selected turn items with cursor and identity
validation.
- Reject unsupported or incomplete history instead of guessing that
execution is idle.
- Trust the startup execution root on its host, including Git worktree
trust keys.
- Start Codex in that root and retain the selected sandbox profile on
later turns.
- Keep unrelated isolated configuration and Codex's separate hook trust
policy.
- Add Rust, TypeScript, accounting, native integration, and local
run-log documentation.

## Verification

- Codex and native-transport TypeScript: 333 passed before PR replay.
- Adjacent OpenCode/ACPX driver and accounting tests: 49 passed.
- Rust library, serialized: 226 passed. Native Codex integration: 72
passed, 1 ignored, plus two pagination regressions.
- Repository typecheck and build passed. All repository test groups have
passing coverage after fixture and resource retests; the initial
monolithic command was not clean.
- Fresh real Codex native browser tasks returned correct answers without
the three targeted notices. Answers persisted after refresh and restart.
- Real same-thread TypeScript driver tests passed locally and in
Daytona, including cold resume, configuration, skills, and an approved
harmless hook.
- Local usage summed to 64,607 tokens. Daytona usage summed to 42,737
tokens. Each sum matched its final session total exactly.
- See doc/plans/2026-09-09-codex-integration-acceptance.md for the scope
and limits of the live tests.
- After replay onto current master and review fixes: 334 Codex, backend,
and live-session tests passed, including checkpoint serialization and
real-runner process restart. TypeScript checks passed.
- The native Codex integration run passed 83 tests; the large lineage
test passed separately with the release runner (its debug build exceeded
the test deadline).
- All GitHub checks passed on the final PR head. Greptile is 5/5 with no
unresolved review threads. CI regenerates the lockfile for the added
TOML dependency, per repository policy.
- The first server shard hit a timing-dependent duplicate-key failure in
the unchanged artifact-document concurrency test. Its focused 11-test
suite passed locally. One CI retry on the same head passed all 103 files
and 1,405 tests (2 skipped): [retry
result](https://github.com/paperclipai/paperclip/actions/runs/34398832930/job/102631274667).

## Risks

- Trust applies only to the server-selected startup root and isolated
configuration. Sandbox and tool permissions remain authoritative.
- Codex still requires approval of individual hook hashes. This change
does not bypass that policy.
- Providers without the required history APIs fail explicitly.
- Daytona acceptance used the production TypeScript driver. Remote
Paperclip UI and remote Rust execution were not tested.
- No new public API, database state, recovery policy, or UI control is
included.

## Model Used

OpenAI Codex, GPT-6 (`gpt-6-astra`). Used for reasoning, code edits,
tool use,
and test execution. The exact context-window limit is not exposed in
this
session. Real-provider acceptance used Codex CLI 0.153.4 with
`gpt-5.6-sol`.

## 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
- [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-09 15:35:18 -05:00
DottaandPaperclip 2991a59b17 fix(adapters): prevent engine fallback and preserve usable runtime defaults (#13105)
## Thinking Path

> - Paperclip manages agents that must write work and report task
outcomes through its API.
> - Local adapters select an execution engine and its permission
settings.
> - A higher ACP Node requirement can make an unchanged installation
lose access to its default engine.
> - The adapter then silently selects CLI, which can change permissions
and block API access.
> - This pull request keeps the engine choice fixed and reports missing
prerequisites before work starts.
> - It also gives explicit Codex CLI runs usable defaults and keeps
managed services on a supported Node runtime.

## Linked Issues or Issue Description

Refs #12215. Related changes: #11792 raised the Node requirement; #13094
addressed separate runner networking behavior. This change fixes the
engine-selection and managed-launcher paths.

**What happened?**

An unchanged agent could switch from ACP to CLI after an upgrade. Codex
CLI then used read-only permissions with networking disabled. The run
could finish without updating its task. Repeated recovery attempts used
the same unavailable setup. Managed updates also skipped the Node check
and did not refresh old launchers.

**Expected behavior**

An unavailable engine must fail with a clear setup error. It must not
silently select another engine. Explicit CLI runs must be able to write
workspace files and call the API unless the operator configures stricter
settings. Managed updates must validate Node and keep child tools on
that runtime.

**Steps to reproduce**

1. Run an ACP-default agent under Node 22 after the ACP minimum rises to
24.11.
2. Leave the engine unset and disable the approval/sandbox bypass.
3. Observe the old adapter select CLI and fail to write task disposition
through the API.
4. Start a managed service with an old launcher and a supervisor PATH
that selects a different Node for child tools.

## What Changed

- Remove automatic engine fallback for Codex, Claude, Gemini, and Kimi.
Check prerequisites for default and explicit ACP selections.
- Return a configuration error with proof that provider work did not
start. Stop automatic continuation retries for this error.
- Enable Codex ACP workspace networking at the actual turn boundary.
Upstream mode presets otherwise force it off even when config.toml
enables it. Preserve explicit network denial and read-only mode.
- Set workspace-write and network access defaults for explicit Codex CLI
runs. Preserve explicit sandbox modes, profiles, and network
restrictions.
- Pin the validated Node directory in managed launcher PATH. Refresh
legacy launchers during installs and npm/Git updates.
- Reject updates on unsupported Node. Keep update checks, dry runs, and
rollback available.
- Synchronize the qualified Codex ACP executable identity across server,
TypeScript runner, Rust runner, and provider-pack launch paths.
- Add regression tests and update engine and installation documentation.

## Verification

- [Full CI passed on the final
head](https://github.com/paperclipai/paperclip/actions/runs/34387099695):
typecheck, build/native runner verification, all general and serialized
test shards, all browser shards, release registry, canary dry run, and
policy checks.
- Greptile: 5/5 on `2c1d6e2815830a5cd39e36c8a082cc0c4441b6c0`, with no
unresolved review findings. Security gates are green.
- Full workspace typecheck and build also passed locally. The final
deployed Linux build passed.
- Full Codex, Claude, Gemini, and Kimi source test suites: 804 passed, 2
skipped. Installer, updater, and launcher tests: 47 passed. Installed
ACP turn-boundary tests: 3 passed. ACP packaging tests: 14 passed.
Focused recovery classification tests also passed.
- Real Linux Codex CLI runs, both fresh and resumed, wrote a workspace
file and reached the control-plane health API with the new defaults.
- Explicit read-only and network-disabled control probes retained those
restrictions.
- A real ACP run on the final deployed Linux build wrote a file and
reached the control-plane API with HTTP 200, without engine fallback.
The same probe failed DNS before the turn-policy patch.
- Executable-identity and installed-policy contracts: 12 passed.
Affected native server tests: 197 passed. Runner factory tests: 21
passed. Rust qualification and native provider integration tests: 11
passed.
- Deployed the production changes to a Linux service on Node 24.20 after
a verified database backup. Health, bootstrap readiness, static UI,
executable/cwd identity, and guarded restart checks passed. The restart
lost no runs.
- Corrected stale Kimi skill-default and Gemini remote-archive fixtures;
both suites pass.

## Risks

- Default or legacy auto engine settings now fail when ACP is
unavailable. Operators who intend to use CLI must select it explicitly.
- Codex CLI now permits workspace writes and networking by default, and
ACP workspace-write turns permit networking by default. Explicit
operator sandbox settings remain authoritative.
- Old managed launchers keep their pinned Node until they are
reinstalled under a supported runtime. An old updater cannot repair
itself; the documentation gives the current installer command.
- Custom service wrappers and global/source installations must configure
their runtime PATH. No database migration is required.

## Model Used

OpenAI Codex, based on GPT-6, with reasoning, repository inspection,
shell execution, and test tools. The exact serving model identifier 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-09-09 13:27:24 -05:00
DottaandPaperclip fac07b42ad fix(runner): preserve durable native session authority across recovery (#13092)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - The native runner carries tool results and task output to the
control plane.
> - A lost connection must not change which run owns a result.
> - A session must not become reusable while provider output is still
pending.
> - This pull request adds strict recovery evidence and bounded drain
barriers.
> - It preserves current PRP version negotiation and session-goal
support.
> - The benefit is safer reuse of native sessions after a transport
failure.

## Linked Issues or Issue Description

Refs #13038. This is the first of two stacked pull requests. It contains
the native runtime prerequisites. The second pull request contains the
experimental chat-channel integration. It preserves the provider
identity and typed terminal-failure contracts in #13074 and the durable
recovery work in #13075.

**What happened?**

Native session failures could leave retained provider events, incomplete
tool results, or warm handoff state that was not safe to reuse. A later
run could observe output from an earlier authority.

**Expected behavior**

Recovery must preserve exact run, tool, process, artifact, and lease
evidence. Uncertain or corrupt state must fail closed. A successful
close must prove that retained provider output is settled.

**Steps to reproduce**

Run the transport and control-plane regressions. They hold and drop
authenticated frames, fail durable writes, and restart fresh controllers
and runner processes with retained state. Provider executables are local
test fixtures.

## What Changed

- Preserve pending provider cleanup and semantic-result evidence across
session close and restart.
- Add an authenticated warm handoff with exact old and new identities,
durable receipts, and completion acknowledgement.
- Drain retained provider events under the cumulative acknowledgement
fence.
- Reject corrupt tool-result contracts without unsafe provider replay or
reusable checkpoints.
- Keep ordinary PRP v1 sessions and current session-goal behavior.
Require negotiated PRP v2 and acknowledged native session evidence
before warm authority rotation.
- Preserve late semantic inputs and exact durable result receipts until
close can prove settlement.
- Add transport, crash-window, artifact, checkpoint, and final-output
regressions.
- Deduplicate resolved execution delivery under the current issue lock.
Reuse the exact existing successor after concurrent scans or a lost
acknowledgement. Preserve newer operator evidence.
- Persist idle provider integrity/capacity failures before process
retirement, retain permanent model-rejection classification, and keep
external question identifiers out of task instructions.
- Expose only the context source on native status events. Keep thin
dispatch projections compatible without exposing the complete context.

## Verification

- Review-fix revision: 128 runtime-context/native-session tests, five
idle-failure/adjacent Rust cases, 24 warm crash-window cases, three
startup-notification/close cases, and five attach/backlog cases passed.
The security and idle-failure cases were first reproduced failing.
- Prior merged revision: runner production build, TypeScript typecheck,
complete Rust workspace tests and formatting passed; 272 focused runner
tests and two real PostgreSQL regressions passed.
- Earlier full runner runs and CI Build failed on missing
semantic-result fixture receipts, stale local provider fixture bytes,
startup-notification ordering, and a confirmation-loss fixture that
could accidentally send its final ACK. Each cause was reproduced and
corrected without relaxing production authority or close assertions.
These earlier runs are retained as failures, not represented as passing
verification.
- The first local repository-wide run failed before later phases because
the isolated install omitted PostgreSQL's native-library aliases; it
also encountered an unrelated occupied-port fixture. Those results are
retained, not represented as a passing run.
- Exact `335b2ee52709afb3885d4d6ebb2a3ece4b5864d6`: the complete runner
suite passed 1,888 tests, with 10 existing skips. The full Rust release
workspace passed with serial test scheduling. The unchanged parallel
Rust run hit the five-second 300-descendant fixture deadline; that
failure is retained. No deadline or assertion was relaxed.
- The resolved-execution regression suite passed 57 tests, including
concurrent delivery, lost acknowledgement, superseded authority, and
newer operator evidence. Plain server typecheck passed. The
duplicate-delivery cases were first reproduced failing.
- Prior exact `335b2ee52709afb3885d4d6ebb2a3ece4b5864d6` CI passed all
required jobs and Greptile reported 5/5. Its local general-server run
passed 7,208 tests but failed one responsibility fixture; later phases
did not run. The fixture started the next wake while its bounded handoff
was active. It also used nonexistent comment IDs, which hid the current
stored-message-author identity rule. The updated tests use real message
authors, preserve task ownership, and await exact automatic handoffs. No
production identity policy changed.
- Current head `aa39275a1f300f7d1a0b16cd0885eea567cff6b0` includes
current master and the native context-source projection. The focused
identity/status cohort passed 27 tests and plain server typecheck
passed. Fresh full repository tests, types, build, required CI, and
Greptile review are pending. Final results will be updated before merge.
- This is deterministic local-provider evidence. It is not a claim of
complete live-provider qualification.

## Risks

- This changes authenticated recovery and close ordering. The TypeScript
transport and runner binary must be built from the same revision.
- Failed or incomplete evidence intentionally prevents reuse and can
require a fresh run.
- PRP v1 ordinary/cold sessions remain supported. A v1 connection lease
cannot upgrade in place. A current v2-capable runner held on a v1 lease
was qualified through owned-process retirement/join, fresh bootstrap on
the same old authority, v2 observation/ACK, then warm rotation. Legacy
binary replacement and adopted-owner migration are not qualified by that
test; rollout must not present them as automatic same-lease upgrades.
- This pull request has no database migration or chat-channel
activation. The second pull request keeps the channel feature
experimental.

## Model Used

OpenAI Codex assisted with implementation, tool execution, tests, and
reconciliation. The existing implementation records OpenAI `gpt-6-astra`
assistance. The current environment does not report a context-window
size. No private reasoning traces are included.

## 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-09-09 11:02:59 -05:00
DottaandPaperclip 82f662656a fix(runner): restore legacy Git access and independent networking (#13094)
## Thinking Path

> - Paperclip runs agents for people with different GitHub accounts.
> - Managed operations must use the intended person's eligible
connection.
> - A failed duplicate connection must not hide a healthy grant for the
same account.
> - Legacy hosts also need their existing Git configuration when managed
access is not configured.
> - Runner networking and local Git operations must not depend on GitHub
broker availability.
> - This pull request separates those policies and improves failure
diagnostics.

## Linked Issues or Issue Description

**What happened?** New runs always cleared host Git credentials and
installed managed launchers. Network permission depended on GitHub
environment variables. A launcher failure could stop even local `git
status`. A newer unhealthy duplicate could take precedence over a
healthy connection, and generic health errors were shown as reconnect
requirements.

**Expected behavior:** Use a healthy eligible managed connection for the
intended account. Preserve host authentication only for unconfigured
standard-trust local or SSH execution. Permit local Git during broker
failures and keep network permission independent of GitHub credentials.

**Steps to reproduce:** Configure healthy and unhealthy grants for one
GitHub account, dispatch an agent, and execute Git commands. Separately
run an unconfigured legacy host with existing GitHub CLI authentication.
Stop the broker and run local `git status`.

**Paperclip version or commit:** Master at 668110469. **Deployment
mode:** Self-hosted. **Installation method:** Git checkout. **Agent
adapters involved:** Native Codex runner and shared adapter execution
setup. **Database mode:** Existing instance database; no migration.
**Access context:** Responsible person's managed grant, or explicitly
unconfigured legacy host. **Node.js version:** 26.4.0 locally.
**Operating system:** macOS development and Linux execution hosts.

**Relevant logs or output:** Previously `GitHub credential context
unavailable` hid configuration, transport, and capability errors. New
diagnostics identify these categories without credential values.

**Additional context:** Refs #13005 and #13022. Dependency provisioning
is addressed separately in #13093.

## What Changed

- Prefer healthy eligible grants and retry credential acquisition once
for the same principal and account before starting an operation.
- Preserve host Git configuration only when managed access is
unconfigured on a standard-trust local or SSH target.
- Project authentication mode and validated Git metadata into native
runner boundaries; refresh resumed provider settings when modes change.
- Enable network access through an explicit standard-trust controller
decision, independently of GitHub. Omitted or restricted decisions stay
disabled; replace warm providers when that decision changes.
- Run local Git with cleared credentials when the managed broker fails,
with specific redacted diagnostics.
- Retry access-refresh conflicts once without treating concurrency as
expired authorization.
- Show retry instead of reconnect for transient GitHub health failures.
Add optional authorization and run-diagnostic fields without a database
migration.

## Verification

- All latest-head CI gates are green, including typecheck, general and
serialized suites, browser tests, canary, native runner verification,
and build. Greptile is 5/5 with no remaining findings; the security scan
passed.
- Full recursive typecheck and build passed. UI token gates passed.
- Full general server run: 7,110 passed, one transient socket hangup;
that file passed on retry. All remaining workspace groups passed,
including 5,552 UI and 478 CLI tests. The complete serialized rerun
passed all 144 suites / 2,179 tests after the initial isolated timeout
passed on retry.
- 195 final launcher and native session tests passed, including
host/managed transitions, local/remote warm network-policy changes,
broker rotation, and attempts to override validated controller
filesystem roots.
- GitHub gateway fallback, duplicate connection selection, refresh
conflicts, per-user reauthorization, and native transport/security
suites passed.
- Additional live native fixtures passed SSH public-key authentication
and a Git credential helper in fresh and resumed host-mode sessions. An
unwritable managed configuration directory preserved local Git (exit 0)
while GitHub CLI failed with `configuration_directory_unavailable` (exit
4). The temporary SSH listener and keys were removed.
- Applicable Rust suites passed except two timing failures under load;
each failed case passed in isolation. The final environment contract
test passed.
- Linux native runner acceptance passed in both managed and legacy host
modes: DNS, HTTPS, npm package download, fresh-worktree Git status,
authenticated GitHub user lookup, repository read, and a new run
continuing the same provider conversation. Managed broker outage
preserved local Git and rejected authenticated access without host
fallback.
- Matching Linux server/runner artifacts and the separate provisioning
repair are deployed to the development instance. A fresh UI-dispatched
task and a new run after a server restart both passed all six shell
checks through the live controller and credential broker. Both runs
selected the expected healthy connection/grant and retained the same
provider conversation. Neither connection was repaired or reconnected.

The sandbox roots are assigned from the validated execution-target probe
**after** ordinary bindings are merged. Regression coverage supplies
forged roots and verifies they cannot override the controller paths.
Networking is enabled only for an explicit
`PAPERCLIP_RUNNER_NETWORK_ACCESS=enabled` controller decision; omitted
values remain disabled.

## Risks

Unconfigured standard-trust local and SSH runs regain access to host Git
authentication resources. Managed, sandbox, plugin, and low-trust runs
do not gain this fallback. Revoked managed access never falls back to
another account. Deploy server and runner artifacts together;
already-started operations retain their captured identity. An
unauthenticated command can still fail when it requires GitHub access.

## Model Used

OpenAI GPT-6 through Codex, with code editing, shell execution, tests,
and browser inspection. The exact model variant 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-09-09 10:15:10 -05:00
DottaandPaperclip 6681104692 fix(runner): preserve provider identity and terminal failures (#13074)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - The runner translates provider events into durable task execution.
> - Provider notifications can refer to another thread or a descendant.
> - Root validation treated these notifications as fatal, and later
layers could lose the original failure.
> - This pull request classifies event identity and preserves structured
terminal failures.
> - The server can then choose safe recovery without weakening tool
authority.

## Linked Issues or Issue Description

Refs #13038. This change incorporates the shared protocol-integrity and
bounded-cleanup prerequisites from that PR. It does not include the chat
feature. Related failure classification work: #13028.

**What happened?**
An informational provider notification for another thread could
terminate the root session. A failed stream could then become a
missing-result error and lose its cause.

**Expected behavior**
Ignore unrelated informational notices with bounded diagnostics. Reject
invalid authoritative events. Preserve the original failure code and
recovery meaning through cleanup.

**Steps to reproduce**
Run a native Codex task. Deliver a notification for an unrelated thread,
or close the stream after a structured failure. Inspect the root outcome
and recorded failure.

**Paperclip version or commit**
Reproduced before e20010472. This branch includes the current
session-goal contract from that commit.

**Deployment mode**
Built from source. Native runner with Codex.

## What Changed

- Classify root, provider-confirmed descendant, stale, unrelated, and
invalid provider events.
- Keep tool requests bound to their original execution authority.
- Preserve typed failures through transport, session, and durable
control-plane cleanup.
- Keep bounded cleanup failures separate from the primary execution
failure.
- Add compatible shared contracts for continuation context, execution
status, and explicit reconciliation. The dependent PR adds their server
and UI consumers.

## Verification

- Runner TypeScript and ACPX suites: 1,733 passed, 7 skipped. Node
contracts: 38 passed.
- Real provider-process fixtures cover 300 descendant identities across
restart, the 4,096-identity capacity boundary, and rejection of
continuation after terminal acknowledgement and restart.
- Repository build, typecheck, and full `pnpm test:run` passed on the
rebased stack (18,448 tests passed, 49 skipped). The full Rust workspace
passed with `--test-threads=1`; parallel execution exposed an existing
fixture port-reservation race. All latest-head CI checks passed. One
unchanged artifact-document concurrency test failed on the first CI run
and passed on its single rerun.
- Added notification, streaming failure, protocol integrity, cleanup
quarantine, and durable failure tests.

## Risks

Provider event classification must retain the new session-goal behavior
on master. Descendant notifications must never gain root tool authority.
Shared contract fields are additive. This PR does not migrate data or
start replacement provider work.

## Model Used

OpenAI GPT-6 through Codex. The exact deployment ID and context window
were not exposed. Used reasoning, tool use, code execution, and browser
automation.

## 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-09 08:53:07 -05:00
DottaandPaperclip 2043e0c735 fix: repair runner configuration, macOS execution, and artifact galleries (#13062)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Agent adapters select a provider, a model, and a runtime.
> - Runner conversion rejected existing Claude agents. The model list
mixed providers.
> - The native Claude runner rejected custom models and could not launch
on macOS.
> - This pull request fixes conversion, model selection, and verified
macOS execution.
> - It also groups configuration fields consistently across adapters and
opens artifact images in the task gallery.
> - Operators can change an agent configuration and run the selected
model on their Mac.

## Linked Issues or Issue Description

**What happened?**

Converting an existing Claude agent to Paperclip Runner failed with a
Codex-only restriction. ACPX Claude showed unrelated models and required
`claude-sonnet-5`. Its native runtime rejected macOS. Configuration
mixed common model settings with process controls. Artifact cards
labeled “Open gallery” navigated to attachment URLs instead of opening
the task gallery.

**Expected behavior**

Conversion keeps agent identity and compatible settings. ACPX Claude
uses the normal Claude catalog and accepts typed model IDs. Codex uses
the native runner. The verified Claude runtime can launch on macOS ARM64
and x64. Common configuration sections place the same fields together
across adapters. Artifact images open in the shared task gallery with
navigation and downloads.

**Steps to reproduce**

1. Open the configuration of an existing Claude agent.
2. Convert it to Paperclip Runner.
3. Select ACPX Claude and a different catalog model or a typed model ID.
4. Save the agent and run a disposable task on macOS.
5. Inspect configuration and advanced run-policy controls across
adapters.

**Paperclip version or commit**

The bugs were reproduced on `165ca56a22adb60e5fda56045442d9c8498116a8`.
This branch was rebased onto `7ed122911`.

**Deployment mode**

Built from source. Local test-drive instance on macOS ARM64 with an
isolated database.

Related work: #11798 addresses unsupported ACP session options in the
existing adapter path. #13048 addresses working-folder preservation.
This change fixes native runner configuration and launch behavior.

## What Changed

- Remove the Codex-only conversion restriction. Preserve agent identity,
instructions, directories, credentials, and compatible model settings.
Reset incompatible sessions while retaining history.
- Show ACPX Claude and native Codex as distinct provider choices. Remove
ACPX Codex from advertised configuration. Normalize legacy
configurations before fresh runs without rewriting historical run
descriptors.
- Select model catalogs and cache entries by provider. Support refresh
and typed model IDs. Pass exact Claude IDs through session creation,
model changes, and recovery.
- Add verified macOS ARM64 and x64 Claude SDK snapshots. Bound
executable allocation and total snapshot size. Preserve package checks,
dependency isolation, process ownership, cancellation, and Linux
descriptor loading.
- Probe local runtime readiness. Report remote platform checks as
incomplete until the remote runner verifies its runtime.
- Surface actual model rejection and allow correction and retry.
- Repair missing ACPX goal-capability helpers exposed by the post-rebase
live test. Persist and restore the optional capability without breaking
session startup.
- Put Agent identity first and intentionally remove the Capabilities
editor, as requested. This is removal of UI editing, not relocation:
preserve existing capability metadata and API compatibility without
adding another editor. Use the themed select for configurable permission
modes, with normal text instead of monospace.
- Put model and provider under Adapter. Give environment variables their
own section. Fold command and arguments under Configuration. Fold
lifecycle, timeout, and interrupt grace under Advanced Run Policy. Hide
single-option permission controls.

- Open image and video artifact cards in the existing task gallery,
including cards in the artifacts panel. Chat attachment images use the
same gallery. Preserve standalone media previews and download links.

## Verification

- Rebased focused UI/API/database suites: 293 tests passed.
- Rebased native runtime and ACPX suites: 242 passed, 7 skipped.
- Repository typecheck, build, and token gates passed for the runner
changes. Gallery follow-up UI typecheck, build, and token gates also
passed.
- Follow-up UI suites passed (86 tests), packaging checks passed (14
tests), and the final focused runtime suites passed (126 passed, 7
skipped).
- Linux container isolation and lifecycle fixtures passed before rebase
(57 passed, 2 skipped). Rust ACPX provider-session tests passed after
rebase (8 tests).
- Browser tests completed actual Claude and native Codex tasks on macOS
ARM64. They covered conversion, catalog refresh, a non-default catalog
model, a typed `haiku` ID, save/reload, cancel, follow-up session
continuity, invalid-model errors, and recovery.
- Final-revision live tests completed a typed Claude task, a follow-up
with the same provider session, and a native Codex task on macOS ARM64.
- Browser tests confirmed the moved interrupt-grace field saves and
survives reload. Cross-adapter tests cover Claude, Codex, Gemini,
process, gateway, and schema forms.
- Full local run: 7,080 passed, 30 skipped, and two timeouts. Both
timeout suites passed on isolated rerun (84 tests); the failures were
the plugin login-worker exit diagnostic and the runner real-server
vertical slice.
- Final follow-up checks: 50 registry tests and 45 snapshot/installation
tests passed (6 platform-specific skips). Oversized executable rejection
is covered before allocation or reading; unsupported-platform tests
invoke the real installation probe.
- Runner head `ddb5101c483a297f74875ab96b3c66035b002d50`: all CI gates
green, including full runner verification, repository build, typecheck,
general/serialized server suites, browser tests, and canary dry run. [CI
run](https://github.com/paperclipai/paperclip/actions/runs/34286178670).
- Greptile: 5/5 on that runner head. All four review threads resolved.
Superagent, Socket, and Snyk checks green.
- After snapshot hardening, another real Claude task completed on this
Mac using the rebuilt runtime.

- Gallery follow-up: 148 focused tests passed, covering artifact
selection, shared attachment collections, deduplication, image/video
cards, standalone previews, downloads, and closing. Live browser
verification completed on the settings follow-up: artifact selection,
6-image pagination with wrapping, download action, and closing all
stayed on the same task URL. All checks passed on gallery head
`96136da58ff195bf6ca00b281eb3022ad12d7bd8`: [CI
run](https://github.com/paperclipai/paperclip/actions/runs/34287987536).
Greptile returned 5/5 on that exact head with no unresolved threads.

- Final settings polish: 96 focused tests, UI typecheck/build, and token
gates passed. A real browser walkthrough verified readable permission
options, identity placement, Capabilities removal, and permission
save/reload. Original test-agent permission mode restored. All 31 checks
passed on final head `e46540d6bf32bfb0566dca16b2f4a75ba437618c`: [CI
run](https://github.com/paperclipai/paperclip/actions/runs/34292797886).
Greptile returned 5/5 with no unresolved threads.

## Risks

- Capabilities intentionally has no editable UI field after this change.
Existing values remain readable and API-compatible; removing the field
does not erase stored metadata.

- macOS launch now copies verified package files into private snapshots.
The implementation must retain isolation and clean up snapshots on exit.
- Runtime provider or model changes reset the current session.
Historical runs remain available.
- The macOS x64 SDK executable digest was verified, but a live Intel Mac
run was not available. Linux verification used container fixtures, not a
real Claude task.
- Remote environment tests report a warning when only the platform has
been checked. They do not claim package readiness from the server host.

## Model Used

OpenAI Codex, based on GPT-6. The exact served model identifier and
context-window limit are not exposed in this session. Used reasoning,
repository inspection, code execution, Rust and TypeScript tests, and
browser automation.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass (focused suites and both
timeout suites on rerun; full-run counts 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-09-08 19:10:09 -05:00
DottaandPaperclip 7ed122911b Add end-to-end session goals to Paperclip Runner
Add capability-aware slash-goal controls, durable provider goal state, PRP v2 negotiation, autonomous goal execution, and safe local session recovery. Integrate with current master, preserve provider session identity, and verify the browser goal/chat/replacement/clear workflow and unsupported-agent rejection.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-09-08 16:18:47 -05:00
DottaandPaperclip 1cc45086d3 feat: use the responsible person's GitHub for shared agent operations (#13005)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Several people can send instructions to the same agent and task.
> - A fixed GitHub token in the provider process can keep the first
person's access after another person's message is accepted.
> - Task ownership cannot select credentials for each accepted
instruction or preserve the identity of an operation already in
progress.
> - This pull request records ordered execution identity contexts and
resolves credentials when managed Git, gh, or GitHub tools start.
> - The benefit is automatic personal GitHub access for shared agents,
with durable continuation rules and no teammate credential fallback.

## Linked Issues or Issue Description

**Subsystem affected**

Cross-cutting: orchestration, connection grants, database, runtime
adapters, native runners, and run details.

**Problem or motivation**

A shared agent must use the person whose instructions it has accepted. A
queued message must retain its author. A retry or approval without new
instructions must retain the originating identity. GitHub must remain
optional for ordinary work.

**Proposed solution**

Persist execution identity separately from task ownership. Give new
processes a run-scoped broker capability and token-free managed
launchers. Capture identity at operation start. Keep an explicit
dedicated-agent grant as an override. Show redacted diagnostics in run
details.

**Alternatives considered**

Per-task ownership, fixed provider tokens, and mutable repository author
configuration do not handle accepted steering or concurrent operations.
A manual account-selection action would add unnecessary setup to each
turn.

**Roadmap alignment**

This completes the existing Multiple Human Users, MCP Tool Gateway &
Apps, Secrets Manager, and Self-healing Runs capabilities. The
implementation follows the maintainer-approved plan.

Related work: Refs #12843, Refs #12907. Existing proposals #4618 and
#8945 cover per-agent or per-worktree author configuration. This change
instead follows the accepted human instruction across runtime types.
Refs #11831 for governed personal connection delegation; this change
preserves connection audience checks and does not use standing
delegation as a personal credential fallback.

## What Changed

- Add durable, ordered identity contexts and active run references.
Preserve message authors through consolidation, steering, retries,
delegation, approvals, routines, and restart.
- Add an authenticated operation-time GitHub credential broker and
local/remote managed git and gh launchers. Keep personal tokens out of
the long-lived provider process.
- Resolve GitHub gateway and server-side Git operations through the same
responsible-person or dedicated-grant selection rules.
- Make absent and unavailable GitHub credentials non-blocking at generic
startup. Clear host and prior-person credentials. Keep anonymous Git
access where supported.
- Add run-detail identity history and the dedicated-account warning.
Keep task ownership and queue-versus-steer decisions unchanged.
- Preserve personal OAuth declarations through connection edits. Retain
exact selected grants in the gateway.
- Fix continuation races found during real acceptance: verify a warm
owner before credential rotation, and wait for bounded durable runner
suspension before the next run starts.
- Make migrations replay-safe. Retain identity through agent/run
deletion, remove it with its company, and clean terminal launcher
directories before releasing execution environments. Document
coordinated release and rollback.

## Verification

- Full workspace typecheck, build, and token gates passed. The complete
local suite passed in its normal test groups: 17,120 passing tests,
including all 143 serialized server suites. After integrating the newly
merged runner API work, full local typecheck and build passed again,
along with 890 focused integration tests. All 31 checks on the
integrated revision passed, including build, browser E2E, release
registry, canary dry run, typecheck, security and all test suites.
Greptile is 5/5 with all review threads resolved.
- Current focused checks passed: 142 native executor tests, 67 runtime
lifecycle tests, 9 durable identity tests, 75 credential/routine tests,
19 low-trust/resumption tests, and the executable migration replay test.
- Authenticated browser acceptance with two Paperclip users and two
GitHub accounts on one shared native agent passed. Real commits and
pushes followed A → B accepted steering → queued A continuation in the
same saved conversation. GitHub commit author and committer identities
matched all three operations. Both runs succeeded and task ownership
stayed unchanged.
- Real GitHub MCP calls switched from A to B after accepted steering. A
delegated subtask retained its originating identity across a server
restart.
- Disabling B's GitHub connection left ordinary work successful. Managed
gh was unauthenticated and the provider had no inherited GH_TOKEN or
GITHUB_TOKEN.
- The browser displayed run-detail diagnostics and the exact
dedicated-account warning. A final controller-restart check followed by
another-person continuation retained the conversation, selected the
correct GitHub login and Git author, and removed each terminal launcher
directory.
- Company-lifetime migration and all five previously failing CI suites
passed locally (167 tests). Same-token gateway A → B → A and six
broker/launcher boundary tests passed.
- Remote callback, launcher, sandbox, and runtime contract tests passed.
Both native and legacy Codex completed actual Daytona executions on the
integrated revision ([campaign
results](https://github.com/paperclipai/paperclip/actions/runs/34155056509)).
The remote package-manager shim staging regression also passed locally.

## Risks

- Deploy the migrations, server broker, launchers, and runner artifacts
together. Existing processes finish with their original contract. New
managed processes need the broker endpoint for GitHub operations.
- Finish or stop new managed executions before rolling application code
back. Keep the additive schema and identity history during rollback.
- Scripts that require a persistent raw GH_TOKEN must use managed git,
gh, or GitHub gateway tools. Run capabilities authorize code executing
within that run to acquire its current identity; this is not
hostile-code isolation within one execution principal. Managed commands
prevent automatic credential carryover; arbitrary code deliberately
copying a credential is outside that boundary.
- Uncertain steering acknowledgement deliberately holds new credential
acquisition until reconciliation. Already-started operations retain
their captured identity.
- GitHub private access and provider outages can still fail the specific
operation that needs them. Dedicated grant failure does not fall back to
personal access.

## Model Used

OpenAI GPT-6 through Codex assisted implementation, review, shell
execution, and browser acceptance. The exact model variant and
context-window size are not exposed in this session. Tool use included
TypeScript and Rust tests, database integration tests, GitHub CLI, and
authenticated 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 (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-07 14:32:20 -05:00
DottaandPaperclip f6a211479f fix: share current CLI runtimes across sandbox adapters (#12994)
## Thinking Path

- Paperclip Runner needs its runtime preinstalled for fast sandbox
startup.
- Native and local adapters should launch one current CLI installation
per provider.
- An older global copy can shadow that installation, and exact native
compatibility pins must match it.
- Update the qualified releases and binary digests, expose shared CLI
entrypoints from the provider pack, and prefer the image-owned bin
directory.
- Keep dependency installation in the image build; task startup only
discovers, links, and verifies artifacts.

## Linked Issues or Issue Description

**What happened?**
Remote native startup rejected a stale global Codex, while CLI-only
images lacked runnerd entirely.

**Expected behavior**
An image-baked runtime starts without uploading binaries or installing
packages. All adapters share the same current provider CLI.

**Steps to reproduce**
Start a native remote task with the old global Codex and the updated
runtime available only under `/opt/paperclip-runner/bin`.

**Paperclip version or commit**
Discovery behavior at `54a99d884`.

**Deployment mode**
Docker with a remote sandbox.

## What Changed

- Prefer `/opt/paperclip-runner/bin`, then the user's local bin
directory, then PATH. Existing metadata and version validation remains
in force.
- Qualify Codex 0.153.4, OpenCode 1.18.29, and Claude SDK 0.3.263 / CLI
2.1.263. Update binary digests, TypeScript/Rust checks, registry
defaults, and the displayed OpenCode version together.
- Share Codex and Claude's native executable with the ACP bridges
through exact dependency overrides. Preserve the separately qualified
ACP bridge implementations and their security patches.
- Expose shared provider-pack CLI launchers; fail the pack build if
Codex ACP resolves a separate Codex installation. Update the eval
image's other agent CLIs to current stable releases and remove duplicate
global provider installs.
- Document the single-current-CLI policy in source comments and
development guidance. Latest stable releases are resolved at
review/build preparation and pinned; task startup never auto-updates.

## Verification

- Native-session and adapter-registry suites: 158 tests passed.
- Provider suites: 88 tests passed, 7 Linux-only checks skipped on
macOS. One existing macOS temporary-path alias assertion passed when
rerun with canonical `TMPDIR=/private/tmp`.
- Package-contract and OpenCode materialization tests: 11 passed.
- Full typecheck, build, and token gates passed. Rust
native-provider/recovery tests: 19 passed.
- Broad local suite: 5,974 passed, 23 failed, 41 skipped. Failures are
in unchanged macOS workspace/path/port and connection suites; focused
runtime tests pass. All latest-head Linux PR checks passed, including
the full test shards, typecheck, build, runner verification, browser
suites, and canary dry run.
- The standalone fleet image built with one current provider CLI each
and passed native Codex/Claude binary-integrity checks. A disposable
Daytona sandbox reported ready in 798 ms; its baked runner completed an
API-key `gpt-5.6-luna` turn in 2,430 ms and returned the expected marker
with a usage receipt. No runtime artifacts were uploaded or installed.
- The normal shared `codex exec` entrypoint also completed an API-key
`gpt-5.6-luna` turn in 2,321 ms.
- Both image builds verify the complete generated lockfile against a
reviewed SHA-256 before package installation or lifecycle execution.
Root lockfile changes remain CI-owned. Merge and rollout remain on hold
for operator review.

## Risks

- Updating provider CLIs changes their behavior for all adapters;
version probes and live native smoke testing are required before image
promotion.
- The image-owned directory takes precedence. Its entries must launch
the same shared CLI as the global PATH, not a private older/newer copy.
- Application qualification pins and the deployed image must move
together. No startup fallback installation is added.
- No schema or authentication-policy changes.

## Model Used

OpenAI GPT-6 (Codex). The session does not expose a more specific model
ID or context-window size. Used reasoning, repository inspection, 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
- [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-07 10:09:29 -05:00
DottaandPaperclip 83987210d6 fix(runner): align direct eval provider setup with qualified runtimes (#12945)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Runner direct live evals test semantic tools against a mock control
plane.
> - The first complete AWS campaign exercised 358 cells.
> - It exposed setup differences from the working full-stack harness.
> - This pull request corrects those direct-harness differences.
> - It preserves production permission defaults and the full-stack
workflow.

## Linked Issues or Issue Description

**What happened?**

Native Codex cells could not find a global codex executable. ACPX denied
unattended tool requests and lost valid provider usage receipts.
AgentCore hit a 30-second facade timeout while its worker allows 120
seconds for delivery. Several models reported a native run result
without updating the separate mock task state.

**What did you expect?**

The direct harness should use the pinned executable, explicit test
permissions, and a timeout compatible with the provider delivery
contract. Its instructions should explain which operation changes mock
task state.

**Steps to reproduce**

Run the full Runner Direct Live Protocol Evals workflow. Baseline
campaign:
https://github.com/paperclipai/paperclip/actions/runs/34059009921.

**Paperclip version**

Master at b55ce03e86. Related public
change: #12932. No duplicate fix was found.

## What Changed

- Resolve native Codex from the pinned Codex ACP dependency, as the
full-stack launcher does.
- Select explicit unattended ACPX permissions only in the isolated
direct eval harness.
- Add a configurable bounded turn-admission wait. AgentCore direct evals
use up to 125 seconds, capped by their turn budget. Other callers retain
the current default waits.
- Explain mock task-state operations separately from native run-result
reporting. Keep all scoring assertions unchanged.
- Bind the direct turn's scope to the current request, rather than stale
shared fixture notes. A provider's end-of-turn result does not authorize
an unrequested mock task completion or extra completion comment.
- Normalize the qualified Claude/Codex usage semantics without
double-counting reasoning or inventing unknown billable categories.
Forward ACPX's persisted terminal prompt-response usage for the exact
current turn; reject stale or ambiguous receipts.
- Preserve the known numeric ACPX token-counter aliases through durable
redaction. Continue redacting strings and credential-shaped values. A
regression test reproduces the previously redacted usage before
normalization.
- Add regression tests and operating documentation.

## Verification

- Passed Runner TypeScript build.
- Passed 88 focused tests across the eval request contract, provider
setup, and Runner transport.
- Passed 93 focused ACPX adapter, sidecar lifecycle, and
usage-accounting tests, including persisted receipt identity and
missing-field regressions.
- Passed 97 additional runtime-host, in-process ACPX driver, OpenCode
proxy, and MCP bridge tests.
- Reproduced the ACPX counter-redaction failure, then passed 36 Rust
decoder/normalizer and durable-redaction tests after the fix.
Credential-shaped strings and objects remain redacted.
- Native Codex get-task-context passed a real provider probe with no
global CLI dependency.
- Local ACPX probes reached a platform startup rejection on macOS;
qualification therefore used the intended AWS Linux fleet. Complete
campaign 34060573948 reached 341/358 passing with zero infrastructure
failures (up from 250/358 and 100 infrastructure failures). ACPX Claude
reached 34/35, ACPX Codex 7/8, native Codex 34/35, and AgentCore 35/35.
Remaining failures were retained in the canonical report:
https://d1p6rlowie26tp.cloudfront.net/runner-protocol-evals/campaigns/gha-34060573948-1/.
- Final complete campaign 34062394019 exercises the current-request
scope clarification with all 358 cells; results pending.
- Passed git diff --check.
- Repo-wide typecheck, build, and tests are delegated to PR CI. They
were not repeated on this machine.

## Risks

- ACPX approval is scoped to the operator-requested isolated fixture
harness. Production defaults do not change.
- AgentCore admission can wait longer, but remains within the whole-turn
budget.
- The mock fixture has no production task lifecycle service. Explicit
task-state instructions describe that boundary; they do not relax
scoring.
- This change does not modify the browser full-stack workflow or its
test fixtures.
- ACPX receipt corrections apply to all native ACPX sessions. They rely
on the pinned qualified server contracts; unknown or ambiguous receipts
stay unknown, and a final accounting-read error never overwrites the
provider's terminal result.

## Model Used

- OpenAI GPT-6 (`gpt-6-astra`) through Codex, with reasoning, tool use,
and code execution. The session does not expose an exact context-window
limit.

## 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-06 17:21:12 -05:00
Dotta 0c1e7504c0 fix(runner): persist warm Daytona workspaces across turns (#12904)
## Thinking Path

> - Daytona preserves a stopped sandbox filesystem, but deleting or
replacing a sandbox removes its only remote copy.
> - Warm reuse therefore improves latency but cannot be Paperclip's
durability boundary.
> - The host execution workspace must remain authoritative after every
successful turn, while same-run recovery must avoid overwriting
unexported remote work.
> - Result proposal, workspace export/merge, and terminal completion
need a durable, replayable ordering so a crash never starts a duplicate
provider turn.
> - A paid browser acceptance suite must exercise both legacy Codex and
Runner Codex for three real turns on one continuously warm Daytona
sandbox.

## Linked Issues or Issue Description

Refs #12901.

Runner Codex did not previously export successful Daytona workspace
changes back to the authoritative host workspace. That made warm reuse
depend on Daytona's remote filesystem and left deleted/replacement
sandboxes without a reliable reconstruction path. The existing paid
fixture also lacked a focused three-turn continuity case for both Codex
adapters.

## What Changed

- Persist versioned, atomic native workspace-sync descriptors and
durable seeds in `PAPERCLIP_HOME`, without credentials or a database
migration.
- Classify fresh, warm, replacement, and same-run-recovery workspace
preparation explicitly; ambiguous lease/root/digest evidence fails
closed.
- Finalize native workspace export/merge after semantic result proposal
and before run completion, with idempotent replay that never submits a
second provider turn.
- Surface legacy Codex workspace restoration failures instead of masking
them, while preserving an earlier provider error when both fail.
- Keep healthy reusable Daytona leases warm for legacy and native
adapters, stamp finalized workspace generations, and retain existing
cleanup behavior for per-turn or unhealthy leases.
- Preserve Runner Codex's provider process/session across warm turns,
including bounded post-terminal tail draining and exact authority
rotation.
- Add the exact paid `daytona-warm-continuity` matrix:
  - `legacy-codex × daytona × warm-three-turn`
  - `runner-codex × daytona × warm-three-turn`
- Drive all three turns through the browser, verify ordered file
continuity and stable lease/workspace/runtime identities, capture
per-turn timings, and delete the sandbox immediately after assertions.
- Document `pnpm test:e2e:runner -- --suite daytona-warm-continuity`; no
package script was added.

## Verification

- `pnpm typecheck` — passed, including migration safety (no migration
added)
- Focused server/runner Vitest coverage — 144 passed
- `pnpm test:e2e:runner:unit` — 114 passed
- `pnpm test:e2e:runner:typecheck` — passed
- `pnpm --filter @paperclipai/paperclip-runner test:codex` — 66 passed,
1 helper ignored
- `native-session-executor.test.ts` — 139 passed, including safe
fail-closed cleanup after remote runner identity capture failure
- Paid local browser acceptance, exact post-rebase Linux/amd64 runner
binary:
- Runner Codex — passed in 1.7m; 3 runs; lease outcomes `created,
resumed, resumed`; 10/10 matchers; cleanup passed
- Legacy Codex — passed in 2.7m; 3 runs; lease outcomes `created,
resumed, resumed`; 10/10 matchers; cleanup passed
- [Protected paid GitHub Actions
campaign](https://github.com/paperclipai/paperclip/actions/runs/34026735033)
against `7da42a91b95fa7fb2df126668ef7e37afb3b2b9d` — passed 2/2:
- Runner Codex — 3 runs; lease outcomes `created, resumed, resumed`;
evidence and cleanup passed
- Legacy Codex — 3 runs; lease outcomes `created, resumed, resumed`;
evidence and cleanup passed
  - Merge/enforcement, S3 history, and Pages publication jobs passed
- Paid result artifacts were scanned for both provider credentials;
neither secret was present.
- Current PR checks — 31 passed, 1 expected Storybook skip; Greptile
5/5; Superagent security scan passed
- `git diff --check origin/master...HEAD` — passed
- Confirmed no `package.json`, lockfile, migration, or SQL changes.

## Risks

- Workspace synchronization now sits on the terminal-success path, so a
remote export failure deliberately prevents false success. Retryable
state retains its lease/seed; loss of the only unexported remote copy
fails closed.
- Warm provider reuse has strict identity and quiescence checks.
Mismatched or ambiguous evidence blocks reuse rather than risking
concurrent provider work.
- The paid suite incurs Daytona and Codex cost only in the existing
protected scheduled/manual workflow and explicitly destroys its sandbox
after each cell.

## Model Used

OpenAI Codex with GPT-5 agentic reasoning, repository inspection, real
browser E2E execution, Rust/TypeScript test execution, and GitHub
Actions diagnostics.

## 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 an existing issue or described the issue
in-PR
- [x] I have not referenced internal/instance-local Paperclip issues or
links
- [x] My branch name contains no internal ticket id
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have documented the dedicated suite invocation without adding a
package script
- [x] I have considered and documented risks above
- [x] All Paperclip CI gates are green on the current revision
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
on the current revision
- [x] I will address all reviewer comments before requesting merge
2026-09-06 08:16:12 -05:00
Dotta af8439a70b feat(runner): restore direct live eval campaigns and reports (#12909)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - The Runner executes agents through native and managed provider
drivers.
> - The direct live eval layer had drifted from the current Runner
contracts.
> - The old local workflow did not provide a complete parallel campaign
or durable report history.
> - The Runner also needed current native OpenCode and OpenRouter
qualification.
> - This pull request restores the direct campaign, corrects the runtime
gaps that the campaign found, and adds safe hosted Evalbook history.
> - The benefit is repeatable model comparison against an immutable
Runner and eval source revision.

## Linked Issues or Issue Description

Refs #11297
Refs #11634

**What existing behavior does this improve?**

This improves the direct live `paperclip-runner` eval workflow, provider
execution contract, and static Evalbook reporting path.

**Current behavior**

The direct evals do not have one maintained full campaign on current
`master`. OpenCode has no qualified multi-model OpenRouter roster.
Parallel provider bursts can compact committed events before the
transport observes them. Local reports do not have a separate safe S3
history index.

**Proposed behavior**

Run one immutable roster-plus-case matrix. Use the shared paid AWS
runner fleet. Keep raw artifacts access-controlled. Publish a sanitized
canonical Evalbook report under the separate `runner-protocol-evals` S3
prefix. Keep immutable campaign directories plus root history, latest,
and latest-green pointers.

**Reason and benefit**

Maintainers can compare native Codex, native OpenCode, ACPX, Claude
Managed, and AWS AgentCore behavior over time. They can inspect failures
without mixing this direct protocol layer with browser full-stack E2E.

**Breaking changes**

None. The new workflow and S3 prefix are additive. The existing Runner
full-stack E2E workflow and report remain separate.

## What Changed

- Added a trusted two-shard direct live workflow for up to 393
roster-plus-case cells.
- Reused the numeric actor allowlist, protected paid environment, and
RunsOn fleet controls from Runner full-stack E2E.
- Added immutable Runner and eval revision resolution, exact credential
boundaries, bounded retries, and cost ceilings.
- Added a public report projection that removes sessions, transcripts,
tool payloads, state, traces, raw failures, remote profile identities,
and credential-shaped values.
- Added additive S3 history under `runner-protocol-evals`, with
immutable campaigns and mutable root index pointers.
- Added native OpenCode model injection and current OpenRouter pricing
contracts.
- Fixed direct eval completion, workflow execution, semantic discovery,
warm-attach state reset, executable binding, and event-burst handling.
- Kept Runner browser full-stack E2E behavior and publication separate.
- Documented local and hosted direct eval operation.

## Verification

- `pnpm --filter @paperclipai/paperclip-runner
test:runner-protocol-eval-publish` — 15 passed.
- `pnpm --filter @paperclipai/paperclip-runner build:typescript` —
passed.
- `actionlint .github/workflows/runner-protocol-live-evals.yml
.github/workflows/runner-full-stack-e2e.yml` — passed.
- Local current matrix at the revision in
[paperclip-evals#17](https://github.com/paperclipai/paperclip-evals/pull/17)
— 323 cells across 10 enabled configurations completed.
- Final local current matrix — 269 passed, 11 behavior failures, and 43
expected macOS-only ACPX platform failures.
- Targeted Runner checks — 13/13 eval-session tests, 15/15
publisher/security tests, and package typecheck passed; complete PR CI
is green, including all browser E2E shards.

## Risks

- Paid live campaigns can consume provider budget. Actor authorization,
exact per-cell ceilings, protected environments, and explicit schedule
enablement bound this risk.
- Public reports can leak provider data. The workflow publishes only a
separately projected report and validates every file before upload.
- The new workflow cannot publish until it is present on the default
branch. This pull request does not change the existing
`runner-full-stack-e2e` publication path.
- The campaign is large. It uses two GitHub matrices and caps combined
concurrency at the shared fleet limit.

> For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and
discuss it in `#dev` before opening the PR. Feature PRs that overlap
with planned core work may need to be redirected — check the roadmap
first. See `CONTRIBUTING.md`.

## Model Used

OpenAI Codex on GPT-5. The exact deployment ID and context-window size
are not exposed. The model used reasoning, code editing, browser
inspection, repository tools, and live provider 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
2026-09-05 20:18:11 -05:00
DottaandPaperclip 3796c6f259 fix(connections): project GitHub identity into sandbox runners (#12907)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Managed GitHub connections resolve a responsible user's or dedicated
agent's identity into an audited, run-scoped credential projection.
> - An enrolled instance could retain a hidden managed setup method
after Cloud stopped advertising it, producing a blank, disabled setup
step.
> - Native runner processes also dropped the resolved GitHub projection
before the provider shell, so `gh` and Git could not use the selected
identity in Daytona.
> - Daytona already provides the outer isolation boundary. Applying
Codex's inner Linux sandbox there both duplicated containment and failed
because nested user namespaces are unavailable.
> - This change repairs setup fallback, carries only the bounded GitHub
projection across each runner boundary, and allows only a
controller-selected managed sandbox transport to act as the outer
sandbox.

## Linked Issues or Issue Description

**What happened?**

An enrolled self-hosted instance could show a blank GitHub setup step
when its managed profile was unavailable. Separately, a native Codex run
in Daytona could resolve a managed GitHub connection on the Paperclip
host but lose it before the provider shell. Once projected, Codex's
nested sandbox failed before commands could run because Daytona does not
expose the user-namespace operation used by the inner sandbox.

**Expected behavior**

Setup must select an advertised customer method when the managed method
is unavailable. A Daytona run must receive the exact managed GitHub
identity selected for that run, support `gh` and HTTPS Git, and rely on
Daytona as its outer sandbox without weakening local or SSH execution.

**Steps to reproduce**

1. Enroll a self-hosted instance while Cloud does not advertise the
managed GitHub profile and open GitHub setup.
2. Observe the blank second step and disabled action.
3. Configure a native Codex agent with a Daytona environment and a
responsible-user GitHub grant.
4. Run `gh api user` or HTTPS Git from the agent shell.
5. Observe missing GitHub environment projection or nested-sandbox
startup failure.

**Paperclip version or commit**

The setup bug reproduces on `1dceee9a4`; the runner proof was developed
from the same branch and verified at the latest head below.

**Deployment mode**

Self-hosted Paperclip enrolled with Paperclip Cloud, using the Daytona
sandbox-provider plugin and native Paperclip runner.

## What Changed

- Wait for connector enrollment hydration, retain a hidden managed
method only while enrollment is needed, and otherwise select an
advertised customer fallback.
- Add a single bounded GitHub credential-environment projection for
`GH_TOKEN`, `GITHUB_TOKEN`, the process-only Git helper token, GitHub
commit identity, and at most 32 controller-generated Git config entries.
- Forward that projection through the durable controller, Codex
app-server transport, and Rust provider child without placing token
values in arguments or config.
- Allow Codex shell inheritance only for the exact projected GitHub keys
and enable provider network access only when the managed credential
exists.
- Derive outer-sandbox authority exclusively from a managed `sandbox`
transport; strip the same flag from configured, host, local, and SSH
environments.
- Define a named external-sandbox permission profile that Codex resolves
to `dangerFullAccess` for default-mode Daytona turns while plan mode
remains read-only.
- Add regression tests for setup fallback, credential projection,
local/SSH/sandbox authority separation, provider forwarding, and
permission-profile selection.

## Verification

- `pnpm exec vitest run ui/src/pages/apps/AppsConnect.test.tsx` — 96
passed.
- `pnpm exec vitest run src/drivers/codex/codex-security-config.test.ts
src/drivers/codex/app-server-transport.test.ts
src/control-plane/durable-prp-control-plane.test.ts` from
`packages/paperclip-runner` — 31 passed.
- Focused native-session executor tests — 3 passed.
- `pnpm --filter @paperclipai/paperclip-runner typecheck` — passed.
- `pnpm --filter @paperclipai/server typecheck` — passed.
- `cargo test --manifest-path
packages/paperclip-runner/runner/Cargo.toml --locked -p
paperclip-runner-core --lib` — 194 passed.
- Real Codex app-server configuration probe accepted
`paperclip-runner-external-sandbox` and reported
`sandbox.type=\"dangerFullAccess\"` while using the named profile.
- [Signed Daytona image
workflow](https://github.com/paperclipai/paperclip/actions/runs/33995270328)
built commit `86571f7997e7100e47bd131aac1f1e773112a0ce`; the isolated
environment was pinned to
`sha256:ecef21105f8de382d75787e59439d936be239b77ae74a31c8ed3a17cde39b023`.
- Live isolated Daytona proof passed: the three projected token
variables were non-empty and equal; the host-scoped Git credential
helper returned the same token without printing it; `gh api user`
resolved `cryppadotta`; authenticated `git ls-remote
https://github.com/paperclipai/paperclip.git HEAD` returned
`1dceee9a4e75b13456760bb54c752deb2dba1d79`; no repository mutation
occurred.
- The persisted 28,476-byte run log contains no GitHub token shape,
bearer header, credential-bearing URL, or private-key marker.
- Latest-head pull-request CI and reviews provide the remaining
full-suite gate.

## Risks

- This deliberately gives shell Git and `gh` access to the run's
resolved GitHub identity. It is the audited class-3 behavior required by
the GitHub connection design and is outside per-tool Ask-first controls.
- The credential source is the trusted broker projection, which
overwrites configured environment values. The helper is scoped to HTTPS
`github.com`, revalidates protocol and host, and never places its token
in command arguments, URLs, or files.
- Managed Daytona sandboxes become the containment boundary for
default-mode provider commands. Local and SSH targets retain the inner
Codex workspace sandbox, and plan mode remains read-only everywhere.

> For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and
discuss it in `#dev` before opening the PR. Feature PRs that overlap
with planned core work may need to be redirected — check the roadmap
first. See `CONTRIBUTING.md`.

## Model Used

- OpenAI Codex, GPT-5, with reasoning, browser control, shell access,
and code execution. The product did not expose the context-window size.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-09-05 17:35:21 -05:00
Dotta bcc6fe7a44 fix(runner): restore multi-turn remote sessions (#12840)
## Thinking Path

> - Paperclip manages AI agents and their work.
> - The runner executes agent turns on local and remote providers.
> - A remote per-turn session must save its state before Paperclip
releases its sandbox.
> - The session runtime returned after 100 milliseconds while the remote
checkpoint still ran.
> - The next turn also checked the local state path instead of the
verified remote backup.
> - This pull request waits for the bounded remote close and accepts
only a verified suspended backup.
> - The benefit is reliable multi-turn execution without weaker identity
checks.

## Linked Issues or Issue Description

**What happened?**

A successful remote agent turn released its sandbox before the runner
saved the verified continuation backup. The next turn failed with
`runner_state_identity_mismatch`.

**Expected behavior**

Paperclip must finish the bounded remote checkpoint before it releases
the sandbox. A later turn must validate and restore the digest-matched
suspended backup.

**Steps to reproduce**

1. Run a native ACPX Claude Plan test in a non-reusable Daytona sandbox.
2. Reject the first plan to start a second turn.
3. Observe that the second turn fails before provider execution.

**Paperclip version or commit**

The failure reproduced at `13775a90b078ff64872f50961ea1b83d575e7bc6`.

**Deployment mode**

GitHub Actions with a Daytona sandbox.

## What Changed

- Wait for the internally bounded remote runner close and checkpoint
before the host returns.
- Preserve the existing short cleanup bound for other providers.
- Validate remote continuation lifecycle from a complete digest-verified
backup when local runner state is absent.
- Keep corrupt, non-suspended, mismatched, and unverified state
fail-closed.
- Make native Plan completion and accepted-Plan wake prompts
deterministic.

## Verification

- A prior 45-cell local campaign passed 44 cells. The only failure was
the OpenCode Plan prompt variance fixed here.
- A focused OpenCode local Plan rerun passed.
- ACPX Claude Daytona message and question cells passed.
- Focused regressions cover delayed checkpoint close and verified remote
backup lifecycle.
- GitHub Build and the focused ACPX Claude Daytona Plan cell will
validate this exact head.

## Risks

Remote runnerd sessions now wait for their internally bounded
close/checkpoint path before returning; generic provider cleanup retains
the existing 100 millisecond bound. Durable run success still cannot be
reversed. The environment release guard still blocks sandbox destruction
when no verified backup stamp exists.

## Model Used

OpenAI Codex, GPT-5.6, extended reasoning, with code execution and
GitHub Actions 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 and contains no internal task
id
- [ ] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [ ] 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 findings
- [ ] I will address all Greptile and reviewer comments before
requesting merge
2026-09-05 06:25:06 -05:00
Dotta 263f181fed fix(runner): complete live hot restart adoption (#12852)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Paperclip Runner owns durable provider sessions and streams their
work to the control plane.
> - Pull request #12845 added native restart recovery for live and dead
local runners.
> - A real browser test found three live-adoption gaps after that pull
request merged.
> - Lazy runner process ownership was not always stored before restart.
> - The old controller did not release its PRP authority without closing
the provider turn.
> - Reconnect events could arrive before the active provider turn was
restored.
> - This pull request closes those gaps and proves the same turn
completes after a UI hot restart.

## Linked Issues or Issue Description

Refs #12845

Related search results: #12646 covers indeterminate command results
after a runner restart. It does not cover controller adoption or
active-turn rebinding. No open duplicate pull request was found.

## What Changed

- Store lazy runnerd process ownership after provider session creation,
read, and resume.
- Detach native PRP controller authority during coordinated hot
shutdown. Keep the live provider turn running.
- Restore the exact checkpointed provider session when bounded PRP
identity events have been compacted.
- Restore the active provider turn before reconnect events are replayed.
This prevents `turn_binding_mismatch`.
- Keep exact live ownership by the current controller out of generic
orphan recovery.
- Add driver, transport, and server regression tests for these paths.

## Verification

- Ran 12 Codex driver lifecycle tests.
- Ran 53 runnerd transport tests.
- Ran 143 recovery and orphan-reaper server tests.
- Ran all 8 real-process restart recovery scenarios.
- Ran all 96 existing runner E2E unit tests.
- Ran runner TypeScript typecheck.
- Ran server TypeScript typecheck.
- Ran the migration replay test and migration safety checks.
- Tested the board UI on an isolated local instance. A real local
Codex-backed turn entered a 120-second terminal wait. The UI `Restart
now` action replaced the server and kept the same runner PID, process
start time, run ID, native session ID, runner ID, provider session ID,
and active turn. The original turn then completed.
- Confirmed one heartbeat run, no retry row, one result, one
proposed-result event, one terminal event, no protocol errors, no active
recovery state, and no surviving runner or provider process.

## Risks

- A live runner can continue provider work while no server owns the
control route. Recovery fails closed when the process fingerprint or
durable identity is ambiguous.
- Provider identity can be restored from the database only for an exact
verified adoption claim. An authenticated live `session.snapshot`
validates that identity before the driver can resume.
- The new detach path applies only to native sessions that expose
restart detachment. Other adapters keep their existing shutdown
behavior.
- This follow-up does not change the database migration or
`package.json`. The migration in #12845 remains replay-safe through `ADD
COLUMN IF NOT EXISTS` and its embedded-Postgres idempotence test. The
dedicated real-process command remains in `doc/DEVELOPING.md`.

## Model Used

- OpenAI Codex based on GPT-5. The exact serving build and
context-window size are not exposed. The run used extended reasoning,
repository tools, shell execution, and in-app browser automation.

## 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 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
2026-09-04 17:54:44 -05:00
Dotta af3023f1e3 fix(runner): repair paid provider startup paths (#12769)
## Thinking Path

> - Paperclip manages AI agents that perform work.
> - Paperclip Runner connects durable task runs to local provider
processes.
> - The full-stack paid matrix exposed failures after the runner
integrity repair.
> - Verified JavaScript entrypoints lost their relative module graph
when Linux executed them through descriptor paths.
> - Returned provider startup errors also remained pending and became
indeterminate after recovery.
> - Sparse Codex tool lifecycle events lost the `write_document`
identity before task transcript projection.
> - This pull request repairs those three boundaries and makes the
structured-question fixture deterministic.
> - The benefit is repeatable provider startup, exact failure replay,
and correct inline Plan placement.

## Linked Issues or Issue Description

Refs #12721 and #12700.

**What happened?**

The paid runner matrix failed ACPX and OpenCode startup before provider
session creation. The runner journal then replaced the original startup
error with an indeterminate recovery result. Native Codex saved a Plan
but rendered it only as a fallback card. A legacy Claude waiting reply
could also echo the reserved terminal marker before the answer arrived.

**Expected behavior**

Verified JavaScript providers must start from immutable
descriptor-backed artifacts. Returned startup failures must persist as
terminal failed command results. Native tool lifecycle updates must
preserve the `write_document` boundary. Pre-answer fixture output must
not contain the reserved terminal marker.

**Steps to reproduce**

1. Run the local provider cells in the Runner Full-Stack E2E workflow.
2. Observe ACPX and OpenCode fail during `session.open` before provider
execution.
3. Observe recovery report `execution_indeterminate` instead of the
original startup error.
4. Run the native Codex Plan cell and observe the fallback Plan card
after the tool activity row.
5. Run the legacy Claude structured-question resume cell and observe an
early marker echo in waiting prose.

**Paperclip version or commit**

`0f9452101740835ce0b1488a204bf48acd5bafc3`

**Deployment mode**

Local development with the paid GitHub Actions acceptance workflow.

## What Changed

- Bundle the ACPX sidecar and OpenCode proxy as self-contained Node ESM
entrypoints before hashing and verified descriptor launch.
- Anchor ACPX dynamic provider package resolution at a
controller-derived provider-pack root and keep that root out of the
provider child environment.
- Persist executor-returned startup errors as redacted durable failed
command results while retaining indeterminate recovery for true process
death.
- Coalesce sparse native tool items by stable ID so a late
`write_document` name, input, and result reach the transcript boundary
once.
- Forbid the structured-question fixture from spelling or announcing its
reserved terminal marker before the user answers.

## Verification

- Rust and TypeScript regression tests cover durable failed replay, true
crash ambiguity, bundle closure, package-root derivation, environment
filtering, exact Codex tool lifecycle coalescing, and prompt
determinism.
- Local execution is intentionally limited to formatters and static diff
checks. GitHub Actions will run tests, type checks, builds, and security
checks.
- After ordinary CI is green, scoped paid cells will validate one ACPX
launch, one OpenCode launch, native Codex Plan projection, and legacy
Claude structured resume before a complete matrix rerun.
- Prior failing matrix:
https://github.com/paperclipai/paperclip/actions/runs/33682434315

## Risks

- Bundling changes the bytes covered by provider launch hashes.
Provider-pack generation already hashes the final built files.
- ACPX still loads qualified provider packages dynamically. The
controller supplies a normalized package root, while existing version,
digest, path, and descriptor checks remain active.
- Durable `failed` is terminal. Replays return the same redacted result
and do not execute the provider effect twice.

> For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and
discuss it in `#dev` before opening the PR. Feature PRs that overlap
with planned core work may need to be redirected — check the roadmap
first. See `CONTRIBUTING.md`.

## Model Used

OpenAI Codex based on GPT-5 with agentic reasoning, repository
inspection, code editing, Git, parallel subagents, and GitHub Actions
coordination. The exact deployed snapshot and context-window size are
not exposed to this task.

## 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 related public work or described the bug in
this PR
- [x] I have not referenced internal or instance-local Paperclip issues
or links
- [x] My branch name describes the change and contains no internal
ticket id
- [ ] I have run tests locally and they pass (intentionally deferred to
GitHub Actions)
- [x] I have added or updated tests where applicable
- [x] No documentation change is required for this runtime repair
- [x] I have considered and documented the 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
2026-09-04 07:58:44 -05:00
Nicky LeachandPaperclip 1c9580e89b test(acpx): bind ACPX credential waits to the real retry envelope (#12780)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - The ACPX runtime host tests manage credentials and sandbox
operations.
> - These tests poll operations that can join quarantine recovery.
> - Recovery uses real backoff and directory synchronization, so the
default poll deadline can expire while the operation makes progress.
> - Three tests also stage a contender before the kernel lease release
completes.
> - This pull request binds every relevant poll and staging call to the
documented retry envelope.
> - The benefit is more stable tests and error output that names the
last observed cause.

## Linked Issues or Issue Description

**What happened?**

Under concurrent test load, ACPX runtime host tests failed while
credential recovery still made progress. Three tests also saw an active
lease after they removed `auth.json`.

**Expected behavior**

The tests must wait for the documented retry envelope before they report
a failure. They must stage a contender only after the credential lease
becomes available.

**Steps to reproduce**

1. Run `npx vitest run src/drivers/acpx/` from
`packages/paperclip-runner`.
2. Run the suite under high concurrent load.
3. Observe intermittent timeout or active-lease failures in
`runtime-host.test.ts`.

**Paperclip version or commit**

`865b4854fb44d3689f1c0ff17e3e715d52aaea73` base commit.

**Deployment mode**

Built from source.

**Installation method**

Built from source.

**Agent adapter(s) involved**

ACPX Codex runtime host tests.

**Database mode**

Not database-related.

**Access context**

Unclear / not applicable.

**Node.js version**

Not recorded in the handoff.

**Operating system**

Not recorded in the handoff.

**Relevant logs or output**

Under concurrent load, the failure included `Timed out in waitFor!`
after 1157 ms and `Managed Codex credential home already has an active
lease`.

**Relevant config (if applicable)**

Not applicable.

**Additional context**

The change touches test code only. It adds no test, removes no test, and
weakens no assertion. The file keeps 28 tests and 146 assertions.

## What Changed

- Add a test-local wait helper with an explicit 10-second deadline.
- Apply the helper to every credential and sandbox poll in
`runtime-host.test.ts`.
- Report the last observed error when a poll reaches its deadline.
- Guard the three credential staging calls that could race with lease
release.
- Set a 20-second timeout on tests that use the long wait.

## Verification

- `npx vitest run src/drivers/acpx/runtime-host.test.ts` passes all 28
tests on the change branch.
- A 40-run concurrent comparison produced zero `runtime-host.test.ts`
failures on the change branch.
- The base comparison produced 13 `runtime-host.test.ts` failures across
40 runs.
- The broader ACPX suite still has a separate
`codex-credentials.test.ts` flake on both arms.
- CI and Greptile results will provide the remaining merge checks.

## Risks

Low risk. The change affects test synchronization only. It increases
selected test wait limits and does not change product behavior.

## Model Used

OpenAI Codex, GPT-5. The model used tool calls and code execution. The
runtime did not provide a context window 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 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 recorded the separate ACPX suite
flake 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-09-03 12:53:57 -07:00