Commit Graph
2 Commits
Author SHA1 Message Date
Devin FoleyandPaperclip 1815474597 fix: report pending execution phase at Stop timeout (#14990)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - The server owns each adapter execution and waits for it to settle
after Stop.
> - A Stop timeout reports that termination remains unverified.
> - Existing phase timings arrive only after their work completes, so a
stalled await has no timing.
> - This pull request samples the pending phase when the Stop timer
expires.
> - Operators can identify the pending operation without treating
diagnostics as stop proof.

## Linked Issues or Issue Description

**What existing behavior does this improve?**

The opt-in Sentry context for an unconfirmed adapter Stop timeout.

**Current behavior**

The timeout includes execution identity but no pending phase. A session
close, instruction collection, workspace restore, or diagnostic write
can remain pending without producing its completion timing.

**Proposed behavior**

Add a closed-list phase and elapsed milliseconds from the exact live
execution control. Sample them when the timeout fires. Report `unknown`
and a null age when the control or attribution is unavailable.

**Reason and benefit**

The next timeout can identify which operation is still pending. It does
not require task text, paths, provider output, or additional database
writes.

**Breaking changes**

No API or execution behavior change. The existing opt-in error context
gains two fields. Related public work: #14639 added Stop identity
diagnostics; #14866 and #14945 cover instruction cleanup and teardown
outcomes. This change adds pending attribution to those paths. The
native Stop work in #14802 remains separate.

## What Changed

- Add a bounded tracker per execution control. Token scopes support
nested and overlapping awaits. A late release cannot clear a newer
scope.
- Track adapter execution, ACP cancellation and settlement, diagnostic
writes, and host cleanup. Keep a coarse host scope until the executor
finishes.
- Sample only the matching current control and settlement promise at
timeout. Freeze the sanitized result. Use a monotonic clock and cap
elapsed time at one day.
- Test stalled operations, repeated Stop calls, stale and wrong-run
controls, callback failures, scope bounds, and the real Sentry SDK
context.

## Verification

- `pnpm -r typecheck` passed.
- `pnpm build` passed.
- Six focused suites passed: 79 tests. They cover pending scopes, Stop
control ownership, real ACP settlement stalls, and Sentry context
isolation.
- The real Sentry SDK contract ran with the audited optional peer
`@sentry/node@10.71.0` installed outside the workspace. Valid phase and
elapsed values were exported; arbitrary labels and nonfinite elapsed
values were rejected.
- An independent agent reviewed the production diff and ran the focused
tests without blockers.
- `git diff --check` and a redacted Gitleaks scan passed. The local full
`pnpm test:run` was stopped during its large serial server batch to
avoid duplicating the sharded CI suite. No complete local broad-suite
pass is claimed.
- All CI gates passed on `c223237b58aa8d479d1c66d7d399de30270bac4f`: 54
successful checks and two expected Storybook skips. This includes the
full sharded test suite, typecheck, build, real Sentry SDK isolation,
browser tests, canary dry run, and the security scan after the PR became
ready for review.
- Greptile scored the same commit 5/5 with no actionable findings or
unresolved review threads.

## Risks

This is diagnostic instrumentation. Cancellation, deadlines, teardown
order, termination proof, and file recovery proof remain unchanged.
Unsupported or uninstrumented work uses a coarse phase. Tracker overflow
fails closed to `unknown`. The tracker emits no new run-log or Telemetry
event. The existing Sentry opt-in gate remains in place.

## Model Used

OpenAI Codex, GPT-6. The agent used code inspection, local command
execution, automated tests, and an independent agent review. The runtime
did not expose a more specific model identifier or context-window size.

## Checklist

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

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-10-02 16:55:38 -07:00
Devin FoleyandPaperclip 0b12ca9532 fix(server): retain context for unconfirmed adapter stops (#14639)
## Thinking Path

> - Paperclip must keep ownership of work until termination is verified.
> - A Stop request waits for the adapter and its cleanup to settle.
> - After 60 seconds, an unconfirmed Stop raises an error.
> - The error currently lacks run, adapter, and runtime context.
> - This makes it difficult to investigate which stop path is stuck.
> - This change adds bounded diagnostics while preserving termination
checks.

## Linked Issues or Issue Description

**What happened?**

An adapter can remain unsettled after its Stop request. The resulting
error says termination is unverified but does not identify the adapter
or run in error monitoring. The optional Sentry setup does not capture
request context, so the endpoint alone cannot fill the gap.

**Expected behavior**

Keep the Stop unconfirmed and preserve its live execution owner. When
optional Sentry is enabled, attach enough bounded context to investigate
the affected run.

**Steps to reproduce**

1. Register an adapter execution control and abort its controller.
2. Leave its settlement promise pending.
3. Wait for the configured Stop timeout.
4. Observe that Stop still fails, but the event now includes the run
UUID, built-in adapter, native/legacy runtime, timeout duration, and
abort-requested flag.

**Paperclip version or commit**

Master commit `17780751551b3bc1c2521f7694026c34534c46c9`; reproduced
with fake timers and mocked optional error monitoring.

**Deployment mode**

Server execution control, including local and hosted runs. Reporting
remains opt-in.

Searched related Stop PRs. #14523 and #14244 address Hermes cancellation
contracts; this change only adds diagnostics to the shared
unconfirmed-stop timeout.

## What Changed

- Use a typed timeout error with the existing message, name, and timer
stack.
- Pass run/adapter/runtime identity from the cancellation owner.
- Add an event-local, allowlisted Sentry context without changing the
default fingerprint.
- Rebuild the reported exception so arbitrary provider fields cannot be
serialized.
- Test timeout ownership, delayed settlement, privacy boundaries, and
absence of context on unrelated events.
- Document the additional opt-in fields.

## Verification

- `pnpm exec vitest run
server/src/services/adapter-execution-control.test.ts
server/src/__tests__/sentry.test.ts`: 38 passed, five real-SDK checks
skipped because the optional package is not installed.
- `pnpm -r typecheck` passed; server typecheck passed again after the
SDK test addition.
- With audited optional `@sentry/node@10.71.0` installed only in local
test dependencies, `PAPERCLIP_REQUIRE_SENTRY_TEST_SDK=1 pnpm exec vitest
run server/src/__tests__/run-failure-sentry-real-sdk.test.ts
server/src/services/adapter-execution-control.test.ts
server/src/__tests__/sentry.test.ts`: all 45 tests passed. The real SDK
uses an in-memory transport; no Sentry requests are sent.
- The broad local `pnpm test:run` command did not complete in the
available verification window and was stopped; no full local-suite pass
is claimed. `pnpm build` passed. All sharded GitHub CI checks passed on
the final PR head.
- Tests use fake timers and a mocked Sentry package; no provider or
monitoring requests.

## Risks

This is diagnostic coverage, not a claim that the underlying stop delay
is fixed. Unknown adapter/runtime values become `unknown`; malformed run
identifiers become `null`. No stop reason, prompt, output, provider
response, credentials, or arbitrary error properties are sent. Timeout,
cancellation acknowledgement, live-owner retention, and retry behavior
remain unchanged. No schema changes.

## Model Used

OpenAI Codex (GPT-6), with reasoning, repository inspection, and command
execution. The session does not expose a more specific model revision or
context-window size.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have described the issue in-PR following the relevant issue
template
- [x] I have not referenced internal/instance-local Paperclip issues or
links
- [x] My branch name describes the change and contains no internal
Paperclip ticket id or instance-derived details
- [x] I have run the targeted tests locally and they pass; full checks
are in progress
- [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 16:38:02 -07:00