Commit Graph
5389 Commits
Author SHA1 Message Date
DottaandPaperclip 2cbca4ceb0 fix: retain channel tools across task continuations (#16806)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Chat channels give an agent tools for its assigned task.
> - Each later run must resolve the task and its accepted requester
again.
> - Some native runs store the task in a database column without the
older JSON fields.
> - Tool discovery read only the JSON fields. GitHub calls also required
a new inbound comment.
> - This pull request uses the durable task binding and accepted request
history.
> - Later runs retain their channel tools while current access checks
still apply.

## Linked Issues or Issue Description

**What happened?**

A GitHub task can find `begin_review` on its first run, then receive an
empty tool list on a later native run. If discovery is repaired alone, a
call can still fail because the later run has no new inbound comment.
Slack and voice tool access also read the older JSON task fields.

**Expected behavior**

A later run for the same task can find and call its assigned channel
tools. The current requester, task, company, agent, endpoint, and access
rules must still allow the call. Revoked access must fail.

**Steps to reproduce**

1. Start a GitHub task and accept its linked requester.
2. Confirm that the runtime can find `begin_review`.
3. Start a later native run with `nativeIssueId`, accepted parent
identity, and no JSON task ID or new wake comment.
4. Search for `begin_review` again. Before this change, the search
returns an empty list.
5. Repair discovery alone and call `read_pull_request`. Before the
request-history fix, the call fails with no active conversation
capability.

**Paperclip version or commit**

Reproduced in source tests before this patch. The branch includes master
at `fa50cab5685b9cdbb26ad9c610cc5b6c373d3ff4`.

**Additional context**

This is a core run-binding bug. The tests use PostgreSQL and synthetic
provider responses. They do not send live reviews, Slack messages, or
phone calls.

## What Changed

- Resolve run task IDs from durable columns, with legacy JSON fields as
a fallback.
- Use the same binding in the gateway, access policy, identity service,
and channel runtime preparation.
- Recover accepted channel request history across later runs. Keep
company, task, agent, and requester boundaries.
- Recover older wake sources through verified parent runs, including
after same-user board follow-ups. Clear the board message’s own legacy
wake fallback. Keep cycle checks without a fixed limit on valid task
history.
- Retain the GitHub origin after a board comment from the same accepted
user. Skip GitHub origin lookup results from other providers.
- Keep ordinary board tools available when the requester changes. Accept
legacy user comments without an author-type field. Still reject explicit
malformed task IDs.
- Prevent a later failure reply from replacing an earlier final GitHub
answer. Recheck this rule under the publication lease.
- Rotate the native tool contract to replace retained sessions with an
older tool list.
- Add continuation, publication, revocation, and boundary tests. Update
the access and feature maps.

## Verification

- Red: the later GitHub assigned-tool search returned an empty list
before the binding fix.
- Red: the later GitHub read failed with no active conversation
capability before the request-history fix.
- Green: runtime MCP discovery, GitHub read/begin/submit review, and
response publication pass for monitor and same-user board continuations.
- Green: Slack history, retained access controls, revocation, and voice
gateway continuation pass.
- Green: 35 channel, failure-publication, legacy-origin, long-history,
and provenance tests pass. Both review findings had failing tests before
their fixes.
- Green: 107 gateway, operation-credential, identity, and provenance
tests pass. These cover both first-run CI failures without changing
their tests.
- Green: 122 runtime, discovery-policy, and native-session tests pass; 2
unrelated tests are skipped.
- Map checks and whitespace checks pass.
- Updated to master in `cfcaba22628772d7fe1fb32b57ff7031c7072781`. The
sole conflict was two tests added at the same location. Both the
continuation test and the publication 403/401 test are retained.
- Current local verification: all 179 gateway, credential,
requester-identity, access-policy, runtime-context, and session-resume
tests passed. Repository typecheck and build passed. Map and whitespace
checks passed.
- The new review regression first returned no source for a same-user
board follow-up over legacy wake metadata. After the repair, all 27
provenance and channel cases passed. The combined GitHub
discovery/read/begin/submit path and revoked access are covered.
- The broader local channel run passed 176 cases and failed four
timing/setup cases: a 15-second Slack authorization timeout,
webhook-verification polling, a Slack acknowledgement deadline, and
Discord setup polling. All four passed in isolation without source,
assertion, or deadline changes. The earlier failure record is retained;
the exact load/order cause is not established. Full CI must pass on the
latest commit.
- Current head: `7b9a08dcbc7b8140b589742f136944270b0496bb`. Repository
typecheck and build pass on this commit. Greptile completed on this
exact commit with 5/5; all four review threads are resolved. The
final-head [CI
run](https://github.com/paperclipai/paperclip/actions/runs/39278921653)
passed: 55 checks passed and 2 intentionally skipped, with no failures
or pending checks. This includes the full sharded test matrix, browser
tests, typecheck, build, and Runner verification. Results were delayed
during the [GitHub Actions
incident](https://www.githubstatus.com/incidents/8tzbpcnl75jp). An
additional unsharded local full test run has not completed; the
completed full-suite evidence is CI.
- Earlier verification: the first PR commit failed two server suites.
Those failures were fixed and verified before this update. The original
4 GiB sandbox could not complete full local typechecking or tests; the
current checkout completed typechecking and build. The full test suite
runs through the CI shards. No full local test-suite pass or live
provider delivery is claimed.

## Risks

- Request history can restore the wrong authority if its scope is too
broad. The resolver checks each accepted parent against the task,
company, agent, and requester. Tests cover invalid and cyclic history.
- The native contract change starts a new provider session for older
contracts.
- No database migration or public API schema changes are required. Each
tool call still checks live access.

## Model Used

- OpenAI Codex, GPT-6 family. The runtime does not expose the exact
deployment model ID or context-window size. The agent used reasoning,
repository tools, code edits, and local 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 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-19 11:20:39 -05:00
Devin FoleyandClaude Opus 5.5 7fed88e78d fix(server): retry heartbeat run read checks after a dropped connection (#16857)
`canActorReadHeartbeatRun` now wraps the issue existence read and the `issue:read` authorization decision in separate `retryIdempotentDatabaseOperation` calls, so one pooled-connection drop (`CONNECTION_CLOSED`) no longer fails heartbeat run, activity, live-event and issue-source reads. Adds a regression test and a note in doc/DATABASE.md.

Refs #15248. Refs #15300. Refs #14773.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 09:17:35 -07:00
DottaandPaperclip 9179d8dcc3 fix: credit Paperclip for managed OpenRouter requests (#16850)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - AI connections choose credentials and routes independently of the
agent harness.
> - OpenRouter assigns app credit from the final request headers.
> - Harness defaults can assign Paperclip work to the underlying
harness.
> - This pull request applies one public Paperclip identity to managed
OpenRouter requests.
> - The benefit is consistent app credit across supported harnesses and
internal model calls.

## Linked Issues or Issue Description

**What existing behavior does this improve?**

App attribution for existing OpenRouter connections and explicit
provider configurations.

**Current behavior**

Requests can omit attribution or carry the harness identity. Paperclip
does not receive consistent credit in OpenRouter rankings.

**Proposed behavior**

Use `https://paperclip.ing`, the title `Paperclip`, and the coding
categories `cloud-agent,programming-app` for managed requests to
OpenRouter. Keep credentials, routing, and unrelated providers intact.

**Reason and benefit**

The provider URL identifies the app across personal and shared API keys.
A search of public issues and pull requests found no duplicate
attribution work. This improves existing AI connections and does not add
a separate roadmap feature.

## What Changed

- Add a shared attribution policy and a parity-checked copy for the
standalone Runner.
- Apply it to managed Codex, Claude, OpenCode, and Hermes connections,
plus native Pi and explicit legacy provider configs.
- Preserve attribution across Codex config filtering, Claude environment
filtering, OpenCode proxy requests, and model-level overrides.
- Attribute direct fast-response and decision-model requests, including
custom connections to the OpenRouter endpoint.
- Add positive and negative regression tests and provider attribution
requirements to the connector playbook.
- Advance native Pi to profile 24, preserving historical identities and
binding the attribution source in its declaration and release checks.

## Verification

- Final head `6df282d2a58c2698e41127443903d6fc85b4b72f`: all CI/status
checks passed or were intentionally skipped; Greptile is **5/5**, with
zero unresolved review threads. [Final CI
run](https://github.com/paperclipai/paperclip/actions/runs/39274938069).
- Focused server/shared/config suites: 132 tests passed before the final
edge-case additions. Expanded adapter suites pass 48 tests; the final
OpenCode merge passes 15 tests; global/EU/US endpoint and policy-parity
suites pass 26 tests.
- Focused Runner suites: 85 tests passed, including model overrides and
recovery/config boundaries. Profile installation/environment/config
tests subsequently passed 72 tests (one optional distribution test
skipped); historical decoding passed 11 tests and updated recovery
coverage passed 27 tests. The Rust profile admission test and all five
native Pi launch/recovery tests passed.
- All 114 managed AI connection tests pass together. They include
custom-header preservation for legacy and native Claude runs, both
OpenRouter and other gateways, inherited headers, and unresolved secret
references.
- Actual requests from installed Codex 0.160.0, Claude Code 2.1.245,
OpenCode 1.18.34, Pi 0.74.0 and 1.0.0, and the managed Hermes runtime
carried all four Paperclip headers. A local endpoint used dummy
credentials and returned an intentional 401 after capture. Codex and
Claude retry requests retained attribution. This proves outgoing header
precedence; it is not a successful model-inference test. The first
Claude capture had an argument-separation error and sent no request;
correcting the command produced the captured requests.
- A live request through `fastResponseModel` completed with `attribution
verified`. OpenRouter recorded generation
`gen-1792420273-Ez1GUTCc7YuZ1FJMCGob` under app ID `3118063`, at a cost
of $0.00000375. The public app record maps that ID to
`https://paperclip.ing/`.
- Full `pnpm -r typecheck` and `pnpm build` passed, including a repeat
after the review fixes. The final server build stamp records commit
`6df282d2a58c2698e41127443903d6fc85b4b72f`. `pnpm check:token-gates`
passed.
- CI first caught the stale Pi source attestation; it is now a new
immutable profile. Greptile caught custom-header loss, now fixed and
covered by the complete managed-connection suite. The next CI run caught
the missing Docker allowlist entry for profile 24; the allowlist and
release smoke pins are now synchronized. Local Docker verification
cannot run because its daemon socket is absent; The exact Docker context
check passed in CI on the final head.
- The initial local `pnpm test:run` did **not** pass. It ran across
source/build edits, reported chat/tool-access collection failures, three
workspace-runtime failures, two new managed-header failures, one Dot
Runner readiness failure, and two native-session-resume failures, and
was interrupted after the final-head CI server coverage passed. Its
secrets suite also reported 91 cases skipped. The isolated tool-access
suite passed all 428 tests, and the complete managed-connection suite
passed all 114 tests. These retries establish recovery, not the cause of
the original local failures; no claim of a successful full local run is
made. Final acceptance uses immutable final-head CI plus the focused
local and live checks above.
- Final-head CI encountered one unchanged UI assertion in
`FileViewerSheet.copy.test.tsx` (missing “Copied link” feedback after
clipboard completion). That shard passed on the earlier head with
identical UI code, and all six clipboard tests passed locally. A timing
race around the asynchronous React update is suspected but not
conclusively established. The single CI retry passed, with no
product/test code changed for it. The earlier failure remains part of
this verification record.

## Risks

- Native Pi profile 24 requires a fresh provider session when
encountering a profile 23 identity; recovery tests cover that boundary.
- Harness upgrades can change header precedence. The playbook requires
actual request capture when changing provider paths.
- Externally managed agents, unmanaged harness settings, and gateways
that replace headers need separate qualification. This change does not
intercept arbitrary model calls made by task scripts.
- The existing OpenRouter entry for the Paperclip URL still displays an
old title, “PrettyFly Opus Testing,” and no categories on the final
public-page recheck. The live request received credit under that URL's
app ID. Public title propagation and leaderboard placement remain
controlled by OpenRouter.
- Global, EU, and US OpenRouter hosts are recognized explicitly; other
subdomains are not treated as OpenRouter. No database migration,
credential ownership change, or Paperclip telemetry event is involved.
Attribution contains public product constants only.

## Model Used

OpenAI GPT-6 through Codex, with reasoning, repository editing, shell
execution, web research, and live API verification. 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 — the focused suites listed
above; the unsuccessful full local attempt is explicitly recorded, with
full final-head coverage supplied by CI
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] All Paperclip CI gates are green
- [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-19 10:28:53 -05:00
DottaandPaperclip a7504784e5 perf(chat): avoid snapshot reads in native progress polls (#16845)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Chat connectors publish safe progress from native runs.
> - A recurring query joins each run to its conversation through JSON
context.
> - Large snapshots make repeated JSON reads expensive.
> - Issue-scoped runs already have a typed issue binding.
> - This pull request uses that binding and retains the legacy JSON
fallback.

## Linked Issues or Issue Description

**What existing behavior does this improve?**

The native chat-progress candidate query in
`enqueueSafeNativeChatProgress`.

**Subsystem affected**

`server/` database queries and chat publication.

**Current behavior**

The conversation join extracts `issueId` from each run's JSON snapshot.
A local plan probes the run repeatedly and reads a large snapshot for
each probe.

**Proposed behavior**

Use the run's typed `issue_id` when present. Read the JSON key when that
column is null. Keep the existing company, endpoint, event, publication,
cursor, and cadence conditions.

**Reason and benefit**

Avoid repeated snapshot reads for scoped runs. Related: #15802 changed
delivery queue scheduling; it left native progress projection on its
existing cadence.

## What Changed

- Change only the native-progress conversation join. Leave the separate
milestone query, which already uses its expression index, unchanged.
- Add a disposable PostgreSQL benchmark that captures the real service
SQL and compares complete rows on one shared fixture. It includes a
legacy null binding, unrelated tenants, 2,400 historical decoys, and 144
KiB of random bytes per snapshot (about 192 KiB after base64 encoding).
- Compare cardinality across independent fixtures. Their generated
conversation and event IDs are not deterministic.
- Add PostgreSQL regressions for a typed issue binding without the JSON
key and for the legacy NULL-column fallback.

## Verification

- Full-size paired local measurement: native baseline 57.67 ms median,
treatment 19.35 ms median, **2.98× faster**. Both return the same 41
complete rows. Five timed samples follow warmups, with baseline and
treatment alternated. The unchanged milestone query is a control.
- An independent full-size run also passed complete row equality and
measured 65.22 → 24.08 ms (2.71×).
- The small 1 KiB control passed the same 41-row equality check and was
neutral: 15.20 → 15.45 ms median. The improvement targets large
snapshots, not small payloads. A repeat of the final JavaScript entry
point also passed equality and measured 2.97× while the full test suite
was running; its wider timing spread is not the primary performance
result.
- Four PostgreSQL cases pass: typed issue scope without a legacy JSON
key, NULL-column JSON fallback, native-progress cadence, and
paused-endpoint no-replay behavior. The remaining tests in that file
were excluded by the name filter.
- Reproduce with `node --import ./cli/node_modules/tsx/dist/loader.mjs
scripts/benchmark-chat-native-progress.mjs --phase=baseline` before
applying the query change. Run the same command with `--phase=treatment`
after applying it. The tool stores SQL, parameters, plans, all samples,
and equality evidence under `.scratch/`.
- Full workspace typecheck and final server typecheck passed locally.
Four focused PostgreSQL cases passed. The duplicate unsharded local
full-suite run was stopped after the same commit passed all CI test
shards; the full local tests/build sequence was not completed. CI Build
and the aggregate verification gate passed on that commit.
- Current-head CI is green at `82c9ef9` (55 successful checks, two valid
skips). An unchanged runtime-supervision test failed in the first
attempt; its isolated local reproduction passed, and one failed-job
rerun passed on the same commit. The local reproduction runs on macOS
and does not exercise the Linux process-identity branch.
- Greptile reviewed `82c9ef9` at 5/5 with no unresolved threads.

## Risks

- The typed issue binding takes precedence when present; older rows
retain JSON fallback. Company and publication ownership checks remain in
the query.
- Measurements use local embedded PostgreSQL 18 with synthetic data. The
hosted motivation used PostgreSQL 17. Absolute timings and plans can
differ on other compute and data distributions.
- The milestone benchmark returns an empty candidate set and is a
performance control; the nonempty native comparison is the correctness
and performance target.
- No schema migration or provider network request is added. This PR does
not deploy a query change to a live database.

## Model Used

OpenAI GPT-6 through Codex, with reasoning, repository inspection, tool
use, and code execution. The exact serving model ID and context-window
size are not exposed. Z-AI GLM 5.3 Prime through OpenRouter
(`openrouter/z-ai/glm-5.3-prime`) assisted the initial query treatment
and benchmark. Codex repaired the comparison, narrowed the production
change, and ran the full-size proof.

## 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

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-10-19 10:20:32 -05:00
DottaandPaperclip fa50cab568 perf(ui): speed task loading without shifting the conversation (#16849)
## Thinking Path

> - Paperclip's board should open a task quickly while keeping its
conversation and composer stable.
> - The browser currently downloads unrelated screens and unopened
dialog implementations before task content appears.
> - Splitting routes alone creates many shared requests and did not
improve measured cold loading.
> - This change groups the startup and task dependency trees, preloads
the task chunk, and defers optional routes and dialogs.
> - Existing coordinated history reveal stays intact so late data does
not insert content above the reader.
> - Hidden routes must not overwrite saved scroll positions with
zero-height geometry.
> - Repeated browser measurements and delayed-response tests establish
the result independently of bundle-file size.

## Linked Issues or Issue Description

Refs #14758. Related prior work: #10463 and #14727.

**What existing behavior does this improve?**

Cold task-page opening downloads and evaluates code for other screens
and globally mounted, unopened dialogs. A direct task link should reach
its saved conversation sooner without moving already-visible messages or
the composer.

**Subsystem affected**

Board UI startup, route boundaries, dialog loading, task scroll
restoration, and the issue-detail performance harness.

**Proposed behavior**

Load optional screens and dialogs when needed, keep startup requests
bounded, and preload the task route. Preserve the current history reveal
policy. Keep the shell mounted during route loading and preserve the
reader's position when a route is temporarily hidden.

**Additional context**

The older bundle-splitting attempt in #10463 is still open from August.
This implementation targets current master and deliberately preserves
today's editor, composer, and transcript reveal behavior. It does not
implement the alternative transcript-row design discussed in #14758.
ROADMAP.md does not describe overlapping startup-bundle work.

## What Changed

- Lazy-load board routes, standalone screens, the legacy layout,
onboarding, and unopened create dialogs.
- Keep activated dialogs mounted across close/reopen to retain their
existing draft lifecycle.
- Group startup and issue dependencies and preload the emitted issue
chunk from the production HTML.
- Contain route loading within the shell and retain existing chunk-error
recovery.
- Contain dialog import failures locally, support cancellation, and keep
setup dismissed after a late download. Warm the task module from task
lists and keep the small chat redirect eager.
- Wait for task-creation dialog fields in the browser fixture before
filling an explicit title.
- Ignore zero-height scroll geometry while a route is hidden.
- Reuse the same persisted performance fixture between builds, record
actual network spans, and distinguish concealed loading content from the
ready thread in browser assertions.

## Verification

- Production UI build and UI TypeScript check passed.
- Recovery follow-up: 74 focused UI tests passed; the cancellation
change passed 23 focused tests plus all 131 onboarding tests (the latter
with a 15-second per-test timeout on the contended local host).
- Setup cancellation was reproduced against the prior production build
and verified fixed after releasing the held real wizard download.
- 91 focused UI tests passed; the final route registrations were checked
again after making standalone screens lazy (33 routing tests passed).
- All eight real-browser layout scenarios passed: delayed comments, late
media, properties changes, growing drafts, older history, Back
navigation, deep links, desktop/mobile same-task links, request
failure/retry, and stalled native/log reads.
- Browser walkthrough: read a populated task, submit one reply, refresh,
navigate to Projects, and return. The reply persisted once and the
normal composer remained usable.
- Token design gates passed. The separate repository-wide publish-token
scan fails on pre-existing references to the local maintainer username
in unchanged files; this change adds none.
- Production-build measurements use the same persisted task, local
API/database, fresh browser contexts for cold opens, and five samples
per scenario/profile. These measurements do not establish deployed
staging latency.
- Final head `076466816a`, consecutive before/after production builds:
five samples per scenario/profile, same saved task and server. Cold Fast
4G/4x CPU content paint: **5,775 → 4,248 ms (26%)**; issue API server
timing was 23 ms in both sets. Warm Fast 4G: 989 → 971 ms. JavaScript
transferred before content: **2,596 → 1,722 KiB (34%)**.
- Unthrottled cold content paint: 1,306 → 676 ms; warm: 269 → 224 ms.
These local timings vary with host load. Earlier measurements showed
about 20% cold improvement, and a contended intermediate run had
substantially higher API latency; those runs are retained in the local
evidence. The final matched pair meets the proposed 25% target, but it
does not establish a guaranteed 25% improvement across environments.
- All four browser scenarios that failed on the first CI run passed
locally after the readiness fixes; the subsequent CI run passed all
eight browser shards.
- Fault-injection browser checks: delayed route loading preserves shell
geometry; a failed route recovers through Back; cancelled or failed
dialog loading preserves an unsent reply; Back dismisses pending setup
and contains its late failure.

- Final head `076466816a`: all CI gates green (55 successful checks, no
pending or failed checks); Greptile 5/5 with no actionable findings and
all review threads resolved.

## Risks

- Dynamic chunks add a loading state on first entry to optional screens
and dialogs. Route failures use the existing error boundary. Optional
dialog failures are dismissible without unmounting the board; retrying a
rejected import requires a reload.
- The task preload prioritizes the primary board journey, including when
another screen is opened first.
- Chunk grouping should be revisited when the dependency graph changes;
bundle size alone does not establish a speedup.
- No API, authorization, migration, editor semantics, or
transcript-reveal policy changes.

## Model Used

OpenAI Codex, GPT-6, with reasoning, repository tools, code execution,
and browser verification. The runtime does not expose a more precise
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-19 10:16:23 -05:00
DottaandPaperclip 06c5bc471d fix(skills): unblock retention for legacy run selections (#16852)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Agent runs can select saved skill versions.
> - The server keeps those files in a cache that must protect active and
unresolved runs.
> - Older runs can lack the newer pin map even when their saved
execution input records the full selection.
> - Finished interrupted runs can also keep a company blocked after all
execution and cleanup have settled.
> - This pull request uses existing selection evidence and recognizes
settled interruptions so safe cache expiration can resume.

## Linked Issues or Issue Description

Related: #16433.

**What happened?**

Skill cache retention reports `unknown_run_pins` for a whole company
when it finds a finished interrupted run without pins, or an older
native run whose complete selection is stored only in its execution
input. Old cache directories cannot expire.

**Expected behavior**

Release pins from fully settled interruptions. Preserve exact versions
from valid saved native selections. Continue to block cleanup when
selection evidence is missing, invalid, or belongs to another run.

**Steps to reproduce**

1. Materialize an old, restorable skill version and let its idle grace
period expire.
2. Add a finished interrupted run with settled ownership and cleanup, or
an unresolved native run with a valid saved execution input but no
modern pin map.
3. Run the retention service. Before this change, it skips the company
with `unknown_run_pins`.

## What Changed

- Treat `interrupted` as terminal only when the existing finish,
controller, finalization, and environment cleanup checks allow it.
- For native runs with no modern pin-map field, parse the saved
execution input with the existing recovery parser. Validate its digests
and company, run, agent, and issue binding.
- Keep captured version IDs protected. Unversioned skills use separate
captured asset bundles. Do not replace a malformed modern map or write
any recovery records.
- Add database regressions and document the fallback. Remove an unused
status list that no longer represented the actual eligibility query.

## Verification

- Passed 41 focused tests: `skill-version-cache.test.ts`,
`skill-version-retention.test.ts`, and
`skill-version-retention-config.test.ts`.
- The tests perform real PostgreSQL reads, directory eviction, and
restoration from saved bytes with upstream unavailable. They cover
leases, unfinished cleanup, invalid digests, invalid versions, and
mismatched identities.
- Passed `node scripts/check-module-boundaries.mjs` and `git diff
--check`.
- A read-only evaluation of the candidate selector against existing
legacy data cleared the unknown-pin blocker while retaining exact
version pins.
- Passed `pnpm -r --workspace-concurrency=2 typecheck` and `pnpm build`.
The full remote CI suite passed, including all server, workspace,
Runner, and end-to-end shards. The full local test command remains in
progress; its focused cache suites passed as recorded above.
- Greptile reviewed this head at 5/5 with no actionable comments or
unresolved threads.
- Initial local database attempts did not run the cases: sandbox access
prevented a listener, then an install with scripts disabled lacked
PostgreSQL library symlinks. After running the package's symlink setup,
the binary started and all focused tests passed.

## Risks

The main risk is releasing a cache still in use. The existing ownership
and cleanup checks remain in force. The native fallback applies only
when the modern field is absent and the saved input passes the same
parser used for recovery. Invalid or missing evidence still blocks the
company. Current versions and explicit agent pins stay protected. Saved
version rows and runtime asset bundles are not deleted. There is no
migration.

The selector reads execution inputs only for legacy native runs that
need the fallback. Normal runs still load only their pin maps and
binding columns. A representative read-only selector check completed in
98 ms; this is a sample, not a latency guarantee.

## Model Used

OpenAI Codex, GPT-6 family, with tool-assisted coding and 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 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-19 10:10:49 -05:00
DottaandPaperclip 9966f31bee fix(chat): keep permission failures scoped to the rejected operation (#16847)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - External channels deliver agent replies through a durable
publication queue.
> - A provider can reject one operation while other operations remain
allowed.
> - The shared error classifier treated generic 403 and permission
errors as failures of the whole connection.
> - Failure handlers then changed the user's enabled setting and removed
all assigned channel tools.
> - This pull request limits permission failures to the rejected
operation and preserves connection intent during authentication
failures.
> - Unrelated work can continue, while confirmed authentication failures
still stop endpoint traffic.

## Linked Issues or Issue Description

Refs #16137. Follows #16138, which distinguishes local authorization
errors from provider errors. This change also narrows provider
permission failures. Related #16806 handles a separate task-continuation
tool-binding defect.

A provider 403 or missing-scope response currently disables a connection
that may still support other operations. The expected behavior is a
visible operation failure with unrelated work preserved. Confirmed
authentication failures must stop sends without changing the user's
enabled setting.

## What Changed

- Classify generic 403, adapter permission errors, and Slack
missing-scope/no-permission responses as failed operations.
- Preserve rate-limit retries, known destination quarantine, and
confirmed authentication failures.
- Preserve connection status and enabled intent when publication,
provider-reply, or form-open authentication fails. The endpoint still
enters attention and its runtime stops.
- Add GitHub regressions for retained discovery and successful later
publication after 403, and no further sends after 401.
- Mark authentication health failed and fence persistent receiver
startup, background reconciliation, and receiver callbacks. Keep signed
GitHub lifecycle events available during an authentication stop. Verify
Discord reconciliation and Photon restart preserve the stop, while
transient Discord disconnects still recover.
- Update provider, publication, and modal regression expectations and
the execution contract and verification maps.

## Verification

- Red: five new classifier cases returned endpoint attention before the
repair. The signed-installation-removal regression also reproduced a
blocked lifecycle event after a 401 before narrowing the receiver guard.
- Green: all 35 classifier tests pass.
- Green: 19 PostgreSQL-backed cases pass through the production channel
services, including GitHub discovery/publication, Slack provider replies
and question modals, Telegram credential/destination failures, rate
limiting, and Discord/Photon authentication-stop persistence.
- Map structural checks and `git diff --check` pass.
- `pnpm -r typecheck` and `pnpm build` pass. All CI gates are green on
`7e379bcd98aa8363e42efe7f8a4b2589b7111ae6`; Greptile is 5/5 on that
exact commit with no unresolved findings.
- The monolithic local `pnpm test:run` was started, then stopped after
its revision passed the full CI matrix and was superseded by the
authentication-stop repair. Final full-suite verification passed in CI
shards; all 19 final local provider regressions pass.
- The tests run from this source checkout on macOS arm64 with isolated
PostgreSQL and controlled provider failures. They do not prove live
GitHub recovery or deployment. No live connection settings were changed.

## Risks

- Permission failures now leave unrelated work available. The rejected
operation remains failed and is not automatically replayed. Provider
authorization still applies to every request.
- Keeping a connection enabled must not bypass an authentication stop.
GitHub verifies blocked tool discovery and later sends; Discord and
Photon verify background reconciliation and restart cannot clear the
stop. Failed connection health is an execution gate while the endpoint
requires attention.
- Explicit disable, disconnect, signed installation revocation, and
existing destination-specific denial handling remain unchanged. No
migration or API schema change is required.
- Previously disabled connections are not automatically re-enabled
because an upgrade cannot safely infer the user's intent.

## Model Used

- OpenAI Codex, GPT-6 family. The runtime does not expose the exact
deployment model ID or context-window size. Used reasoning, shell tools,
repository edits, 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 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>
canary/v2026.1019.0-canary.7
2026-10-19 09:54:22 -05:00
DottaandPaperclip 016e40d532 fix(recovery): preserve shutdown export ownership through finalizer drain (#16843)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Legacy adapters must save sandbox files before Paperclip releases
their source.
> - Graceful shutdown gave each adapter a shared 30-second settlement
wait.
> - When that wait ended, cleanup could stop the sandbox while the
adapter still exported files.
> - That race created a restore failure and blocked the next turn.
> - This pull request keeps export ownership through the finalizer drain
and renews its cleanup fence.
> - A successful late export can release its source and schedule one
bounded continuation.

## Linked Issues or Issue Description

Refs #15857. This corrects the timeout path introduced by the shutdown
settlement fence.
Refs #16478. That repair clears verified historical holds; this change
prevents an active export from losing its source.
Refs #16835. That merged fix handles remote native runner ownership.
This change handles legacy shutdown settlement.

## What Changed

- Keep a late adapter settlement in the shared execution finalizer set.
Wait for it before lease release, recovery classification, and retry
scheduling.
- Renew the exact owned settlement fence every 10 seconds. Use a
30-second lease, one renewal in flight, a one-second database lock
timeout, and a five-second statement timeout. Report bounded failure
categories without raw database errors or credentials.
- Refuse ordinary cleanup while the local adapter still owns settlement.
Preserve the explicit owner stop-and-retain path.
- Give the finalizer drain a further shared 30-second wait after the
initial shutdown drain.
- Document the ownership rule, the acceptance recipe, and the
controller-loss limit.

## Verification

- Red before the repair: the database-backed expired-wait regression
expected cleanup denial but received permission to stop the still-owned
source.
- Green on `615a4382c5`: all 526 tests in `recovery.test.ts`,
`legacy-workspace-restore-recovery.test.ts`, `shutdown.test.ts`, and
`heartbeat-process-recovery.test.ts` passed.
- The assembled heartbeat regression passed. It verifies no early
release or retry, joining the late owner, successful cleanup, one
durable scheduled continuation, and no duplicate after service reload.
- Safety coverage includes other-controller fencing, controller loss,
exact source retention, stop-only cancellation, completion winning the
status race, and real database lock contention during renewal.
- `pnpm -r typecheck`, `pnpm build`, and `node scripts/check-maps.mjs`
passed on the final source revision.
- A broad local `pnpm test:run` crossed the rebase and reported eight
companion supervision failures. It was stopped and its log retained. The
complete companion file then passed all 753 tests on current source.
This is not a passing full local suite; current-head CI covers the
complete repository checks.
- The 34 recovery tests include real lock-timeout classification and
credential-shaped error redaction.
- Current-head CI: 53 checks passed; two optional Storybook checks
skipped. Greptile is 5/5 on `615a4382c5`; no unresolved review threads.
- Live sandbox acceptance remains unverified. Three disposable
local-controller/Daytona attempts used legacy Codex ACP, `gpt-6-astra`,
API-key authentication, and the verified image
`ghcr.io/paperclipai/paperclip-daytona-runner@sha256:a2bd08cefb68d9217bdd75cf87a6b51f1705b18a4796eff3f97b2726a548b8fb`.
ACP initialization exited before model execution on macOS Node 26.4.0
and again on Node 24.21.0; one attempt exposed a local process-session
socket `ECONNRESET`. That does not establish the transport failure's
root cause. No attempt reached the delayed export or second turn, so
this PR remains draft pending faithful live acceptance. Probe setup
defects were retained separately from product failures, and all
test-owned sandboxes were cleaned up.

## Risks

- Shutdown can spend up to 30 more seconds joining finalizers. The
shipped Compose stop grace remains 90 seconds.
- Renewal adds at most one database operation per owned run every 10
seconds during shutdown. Lock and statement deadlines bound database
contention. The local adapter still protects its source if renewal
fails.
- Controller death or an export that outlives the whole process still
needs retained-source repair. This change does not reconstruct a legacy
export after process death or clear historical failed-restore holds.
- No schema or public API changes. Native restart ownership, approval
gates, and retry limits retain their existing behavior.
- This PR has not been deployed. It does not recover an existing
retained sandbox by itself.

## Model Used

OpenAI Codex, GPT-6 family, with reasoning, repository inspection, code
execution, and test tools. The exact backend model identifier and
context window were not exposed to this session.

## Checklist

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

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-10-19 09:19:09 -05:00
Naeem Akhtar 0ed760ce9a fix(server): keep local authorization failures from disabling chat endpoints (#16138)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - Chat endpoints publish agent replies to providers such as GitHub,
and a durable outbox classifies each send failure
> - A GitHub review run that fails posts a "review failed" reply. When
the run has no request binding, Paperclip throws its own `forbidden()`
before any GitHub request
> - The classifier reads that local 403 as a provider credential
failure. The endpoint goes to `attention`, its tool connection is
disabled, and new `pull_request` webhooks are dropped
> - One failed review can stop all reviews on that endpoint until an
operator reconnects it
> - This pull request classifies Paperclip's own 401/403 `HttpError`
without a provider status as a failure of that publication only
> - The benefit is that only real provider credential failures lock an
endpoint

## Linked Issues or Issue Description

Fixes: #16137

## What Changed

- `server/src/services/chat-publication-errors.ts`: an `HttpError`
(Paperclip's own class) with status 401 or 403 and no numeric
`details.providerStatus` returns `{ kind: "failed" }`. The check runs
before the credential branch.
- Provider errors do not change. Adapter
`AuthenticationError`/`PermissionError`, Octokit errors (named
`HttpError`, but not this class) and Paperclip-wrapped provider
rejections that carry `providerStatus` still return
`endpoint_attention`.
- `server/src/services/chat-publication-errors.test.ts`: a new test
covers a local `forbidden()`, a local `unauthorized()` and a wrapped
provider 403.

## Verification

- `pnpm --filter @paperclipai/server vitest run
src/services/chat-publication-errors.test.ts`
- I ran the classifier source with type stripping on Node 22: local
`forbidden("GitHub failure has no request binding")` → `failed`; local
`unauthorized()` → `failed`; `new HttpError(403, …, { providerStatus:
403 })` → `endpoint_attention`; an Octokit-shaped 403 →
`endpoint_attention`.
- I applied the same change to the built `dist` of a self-hosted install
and called its classifier with the same four errors. The results were
the same.

## Risks

- Low risk. The change applies only to Paperclip's own `HttpError` with
status 401/403 and no provider status. Such an error now fails one
publication and does not disable the endpoint. Code that throws a local
401/403 to report a provider credential problem must attach
`providerStatus`. I found no such caller in `server/src/services`.

## Model Used

- Claude Opus 5.5 (`claude-opus-5-5`, Anthropic), in Claude Code with
tool use (shell, file edits, test runs). It helped to find the cause,
write the change and the test, and run the checks.

## 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 (classifier checked with
type stripping; the full vitest suite runs in CI)
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [ ] 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
canary/v2026.1019.0-canary.6
2026-10-19 08:57:18 -05:00
DottaandPaperclip 56e09cd19f docs: add native Runner integration playbook (#16846)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Native Runner connects those agents to harnesses through provider
drivers.
> - Adding a harness crosses protocol, setup, lifecycle, packaging, and
product boundaries.
> - Existing guidance does not provide one complete procedure for this
work.
> - This pull request adds a native Runner skill, detailed playbook, and
working templates.
> - Contributors can use them to define a release, implement the
integration, and verify the delivered result.

## Linked Issues or Issue Description

**Issue type**

Missing documentation.

**Where is the issue?**

Native Runner contribution guidance in `doc/DEVELOPING.md` and
`packages/paperclip-runner/README.md`.

**What's wrong?**

Contributors must reconstruct the requirements, protocol mapping, normal
setup, lifecycle rules, packaging, and acceptance process when they add
a harness. The legacy direct-adapter recipe covers a different execution
path.

**Suggested fix**

Add a self-contained native Runner procedure. Include capability
research, a finite release contract, implementation boundaries,
reproducible tests, normal installation, and release evidence. State
each lesson directly so contributors need no private chats, tasks, or
evidence archives. The duplicate search found no existing playbook PR.

## What Changed

- Add `create-runner-adapter` for new native Runner harness
integrations.
- Add a detailed playbook based on the Pi, Cursor, and Copilot
integration lessons.
- Cover model and instruction admission, connection setup, rich events,
durable interactions, recovery, cancellation, packaging, and Product E2E
acceptance.
- Add templates for scope, capabilities, attempts, failures, jobs, and
release handoff.
- Link the procedure from the development guide and Runner README.
- Keep legacy adapters as a compatibility boundary.

## Verification

- `git diff origin/master --check` passed.
- `node scripts/validate-doc-links.mjs` passed from
`packages/paperclip-runner` and checked 53 documentation files.
- All 71 Markdown links in the new reusable files resolve to repository
paths or public provider documentation.
- Skill YAML, naming, description, and scaffold checks passed.
- A private-reference audit passed for the reusable skill, playbook, and
templates.
- The legacy direct-adapter skill matches the base version.
- Full local runtime checks were attempted with pnpm 9.15.4. `pnpm -r
typecheck` stopped because Node type definitions are missing. `pnpm
test:run` and `pnpm build` stopped because `cli/node_modules/tsx` is
missing. This checkout has no installed dependencies. These commands did
not establish runtime test or build results.
- Full remote CI passed on commit
`88b4fc4832d95807da1f5e48029a183b3dc62b6c`: build, typecheck, general
and serialized server tests, Runner checks, browser tests, and the
canary dry run. [CI
run](https://github.com/paperclipai/paperclip/actions/runs/39262297681).
- All 55 applicable checks passed. The two Storybook checks were skipped
for this change.
- Greptile gave the current commit 5/5. There are no review comments or
unresolved threads.

## Risks

Low risk. The procedure can drift as the Runner contracts and test entry
points change. It records its source baseline and tells contributors to
inspect current declarations. Historical lessons describe failure
patterns; they do not certify current binaries.

## Model Used

OpenAI Codex with `gpt-6-astra` and `gpt-6.1-sol`, both using xhigh
reasoning. Context-window sizes were not exposed. The models used
repository search, terminal tools, and file edits.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used, including available version and
capability details
- [x] I have checked ROADMAP.md and confirmed this documentation does
not duplicate planned core work
- [x] I have searched GitHub for duplicate or related PRs
- [x] I have described the issue in this PR using the documentation
issue template fields
- [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 or instance details
- [x] I have run the relevant local documentation checks; they pass.
Blocked runtime checks are recorded above
- [x] I have considered tests for this documentation-only change and
validated its links and skill metadata
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented the 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 merge

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-10-19 08:50:44 -05:00
DottaandPaperclip 98ca6ff7c5 perf: reuse verified provider files during sandbox startup (#16493)
Build provider-pack transport layers once, reuse verified image files in private directories, and upload only missing layers. Preserve archive integrity checks and directory fallback on unsupported hosts.

Verified with 44 focused tests, all 48 main CI jobs, cloud Docker Runner checks, and Greptile 5/5 on the merged head.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-19 08:45:09 -05:00
DottaandPaperclip 661b104e04 docs: discourage utility scripts in package manifests (#16842)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Its review process protects package manifests because they define
dependencies.
> - New convenience scripts also change these protected files and cause
extra review.
> - Greptile needs a clear instruction to discourage these additions.
> - This pull request adds the requested sentence to the Greptile
prompt.

## Linked Issues or Issue Description

**Issue type**

Missing documentation.

**Where is the issue?**

The repository review prompt in `.greptile/rules.md`.

**What's wrong?**

Agents add package scripts for utilities and specialized checks. These
additions trigger the extra review intended for protected package
manifests. No duplicate open PR or issue was found in the GitHub search.

**Suggested fix**

Add this exact instruction: Do not add package.json scripts for new
utilities, checks, benchmarks, or specialized tests.

## What Changed

- Added the requested sentence to `.greptile/rules.md`.

## Verification

- `git diff --check` passed.
- Confirmed that the diff contains only the requested sentence and its
separating blank line.
- Local prompt and PR-template checks passed.
- Full typecheck, test, and build checks were not completed. This
worktree has no installed dependencies. The typecheck attempt stalled
during pnpm startup and was stopped; the test and build commands were
not run.

## Risks

- Low risk. This changes review instructions only. Greptile may flag
future additions in the listed categories.

## Model Used

- OpenAI GPT-6 through Codex, with repository inspection and shell
tools. The exact runtime model ID and context window size were not
exposed to this session. The user supplied the added sentence verbatim.

## 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 prompt and
PR-template checks only; full-suite limits are recorded above)
- [x] I have added or updated tests where applicable (no new tests
needed for this prose-only change)
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [ ] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-10-19 08:38:10 -05:00
DottaandPaperclip f3cd3f4ea8 fix(runner): require confirmed exit before remote replacement (#16835)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Remote runs need one runner to own their process identity and
listener.
> - A health request can fail while that runner continues to work.
> - The active monitor treated a failed request as a process exit.
> - Recovery could then launch another runner against the occupied
listener.
> - This pull request retries health reads and requires proof of exit
before replacement.
> - A brief outage can recover on the same runner without replaying
agent work.

## Linked Issues or Issue Description

Refs: #16341 adds remote recovery diagnostics. Refs: #16686 retries
verification when restoring a saved remote session. This change applies
the shared probe policy to active process supervision.

**What happened?**

The active remote monitor settled its completion promise after a
timed-out or rejected health request. The transport treated that result
as an exit and started process recovery. An existing runner could still
own the listener. Replacement then failed with
`runner_ingress_bind_conflict` until the reconnect deadline expired.
Missing or changed ownership markers also did not prove that the old
process had exited.

**Expected behavior**

Retry transient read failures on the same runner. Require a matching
ownership marker and proof of process exit before replacement. Preserve
uncertainty when identity or liveness cannot be verified.

**Steps to reproduce**

1. Start a remote runner and leave its listener alive.
2. Make one process-health request time out or reject.
3. Observe completion and the restart decision. Before this change, the
monitor settles while the process is alive, and the restart wrapper
permits another launch.

**Paperclip version or commit**

The defect was reproduced on master at `6e89919631`. The patch is based
on current master at `c6a0cf4bce`.

## What Changed

- Reuse the bounded read-only recovery probe for active supervision.
Retry up to three reads within 30 seconds.
- Check the saved process generation when available. Accept only the
specific process-not-running receipt as exit proof.
- Add an exit-confirmation contract to remote process handles. Require
it for restart and shutdown completion. Preserve the cause of
supervision errors.
- Test transient failures, exhausted retries, conflicting identities,
real listening processes, and an authenticated runner with a fake
provider. Keep confirmed-exit replacement covered.
- Document the recovery policy and coverage limits in the execution
contract and maps.

## Verification

- Red: the timeout and transport-error regressions failed before the
patch because completion settled while the runner was alive. The
restart-guard regression also failed because replacement was allowed.
- Green: 14 server supervision cases passed, including a real listening
process. All 120 shared control-plane tests passed. Focused Runner tests
passed for authenticated live-runner fault injection and confirmed-exit
replacement.
- Review regression: a replacement-health test first failed because its
error cause was lost. It passed after preserving the cause and detail.
The four affected transport cases and Runner typecheck then passed.
- `node scripts/check-maps.mjs` passed for 35 areas and 176 capability
IDs.
- `pnpm -r typecheck` and `pnpm build` passed locally. The sequential
local full-suite run was stopped before completion; no local full-suite
pass is claimed. Final commit `bcc1b1d339` passed the complete CI
matrix: 55 checks passed and two optional Storybook checks were skipped.
Greptile is 5/5 with no unresolved conversations. The PR has no merge
conflicts.
- The first real-listener attempt could not bind inside the execution
sandbox. The same test passed with local socket access. The first
package-test invocation used the root configuration and selected no
tests; the package configuration ran all selected tests.
- CI attempt 1: nine test jobs were cancelled together at 12:54:59 UTC.
Their test steps report cancellation. The build and uninterrupted jobs
passed. The interrupted jobs were retried once. That retry exposed one
confirmed-exit message assertion failure in the Runner shard; the other
jobs passed. The compatibility correction preserves the prior message.
The failing case and four recovery cases then passed locally. The
complete CI matrix passed after that correction.
- No live sandbox restoration, deployment, or historical task recovery
is claimed.

## Risks

- A persistent outage now ends supervision with explicit exit
uncertainty. It cannot authorize a competing process. Existing ownership
and workspace recovery checks remain required.
- Health reads can take up to 30 seconds before reporting an unavailable
runner. Retries are read-only and bounded.
- Local launchers keep their existing completion contract. No database
migration or public API change is required.

## Model Used

OpenAI GPT-6 through Codex, with reasoning, tool use, and code
execution. The exact serving snapshot 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>
canary/v2026.1019.0-canary.5
2026-10-19 08:19:37 -05:00
DottaandPaperclip 9077748894 Remove the Pipelines experiment and preserve its data (#16834)
## Thinking Path

> - Paperclip manages AI agents and their work.
> - Pipelines was an unused experiment with its own UI, API, CLI, and
automation.
> - Keeping it leaves unsupported product surfaces and extra task-detail
queries.
> - Removing the experiment must preserve data that users already saved.
> - This pull request removes the feature and keeps its database schema
and migration history.
> - Cases and Routines remain available as separate features.

## Linked Issues or Issue Description

**What existing behavior does this improve?**

Remove the unused Pipelines experiment across the application.

**Current behavior**

The experiment includes pipeline boards, stage settings, case
automation, review queues, learnings, permissions, and CLI commands.
Task detail also queries pipeline links.

**Proposed behavior**

Remove all these product surfaces and their implementation. Preserve
existing tables, records, and documents. Ignore the retired boolean in
older managed configurations so upgrades still start.

**Breaking changes**

Pipeline URLs, API endpoints, CLI commands, and `pipelines:write` are
removed. Task detail no longer includes the old `linkedCases` field. The
independent Cases API remains available. No database migration or
cleanup is included.

Related feature work: #7907, #9110, #10905, #11375, #13004, #14671,
#16133. Related issues: #9663, #10310, #10312. This removal supersedes
the feature; it does not implement those pending enhancements or delete
their saved data.

## What Changed

- Remove Pipeline UI pages, navigation, gates, clients, query keys,
helpers, and unused design tokens.
- Remove Pipeline REST routes, services, automation dispatch,
task-detail queries, and OpenAPI discovery.
- Remove the CLI commands, shared contracts, experimental flag, catalog
entry, and permission defaults.
- Remove feature-specific tests, tutorials, smoke scripts, maps, and
Storybook examples.
- Preserve database schema, migration history, and the reserved document
key used by old records.
- Keep Cases routes independent and cover obsolete stored and managed
settings.

## Verification

- Passed: `pnpm build` and `pnpm -r typecheck`.
- Passed: targeted settings, managed configuration, sidebar, settings
UI, routing, and feature-catalog tests. A first sidebar run caught a
shared Workspaces icon import; the import was restored and the sidebar
rerun passed.
- Passed: 40 tests covering Cases routes, OpenAPI discovery, retained
Pipeline table constraints, and schema snapshot drift.
- Passed: token gates, map validation, generated API metadata check,
Storybook catalog validation, and 28 map/catalog tests.
- Passed: isolated local browser verification of navigation and
Experimental settings with Pipelines absent; Cases and Routines still
open normally. Live GET/POST requests to retired Pipeline endpoints
return 404, and the retired setting is absent. CLI help has no Pipeline
commands.
- Passed: 22 access-service and agent-default-grant tests after
restoring unrelated permission assertions flagged in review.
- Local full run: `pnpm test:run` reported one failure in the unchanged
workspace-runtime port-allocation test. That test passed in an isolated
rerun. The long local run was stopped after full CI passed; it is not
reported as a complete local pass.
- Passed: all 56 checks on `def9181f3a4491d95fca1d38e9739f5b821aae3e` (2
conditional checks skipped), including build, typecheck, test shards,
and browser suites. Eleven interrupted CI jobs reported “The operation
was canceled”; their one-time retry passed. [CI
run](https://github.com/paperclipai/paperclip/actions/runs/39255211006).
- Greptile: 5/5 on the final commit, with the only review finding fixed
and resolved.
- Sandbox socket restrictions affected the first build/API test
attempts. The same commands ran with local sockets available.

## Risks

- Existing Pipeline clients must stop using the removed endpoints and
commands.
- Existing data remains in the database and backups, but the removed UI
no longer displays it.
- Historical boolean `enablePipelines` values are ignored. They cannot
restore the feature.
- Cases and Routines must retain their separate behavior. Targeted route
tests cover this boundary.

## Model Used

OpenAI Codex, GPT-6, with repository inspection, editing, shell
execution, and browser verification. The exact deployed model ID and
context-window size are not exposed in this session.

## Checklist

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

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-10-19 08:09:46 -05:00
DottaandPaperclip f96a1e6406 refactor(skills): keep test audit evidence in tasks and PRs (#16833)
## Thinking Path

> - Paperclip manages AI agents that perform work.
> - The test-audit skill guides test maintenance.
> - Its Paperclip reference tells agents to commit audit receipts under
doc/plans/.
> - This adds repository documents to small test cleanups, as seen in
#16639.
> - This change keeps audit decisions and validation evidence in the
task and PR description.
> - Test gardening creates no repository documentation unless a human
asks for it.

## Linked Issues or Issue Description

**Where is the issue?**

`.agents/skills/test-audit/references/paperclip.md`, with related
reporting instructions in the entry point, campaign guide, and
validation reference. Related example: #16639.

**What's wrong?**

The skill requires repository audit receipts. A six-line test deletion
in #16639 added an 88-line report under doc/plans/. The task and PR
already provide a place for this evidence.

**Suggested fix**

Keep the evidence in the task and a concise PR description. Require an
explicit human request before changing repository documentation during
test gardening.

## What Changed

- Removed the instruction to commit dated audit receipts under
doc/plans/.
- Added the reporting rule to the skill entry point.
- Directed campaign ledgers and plans to the task.
- Kept the existing coverage, validation, and delivery requirements.

## Verification

- Skill validation passed with `quick_validate.py` from the
skill-creator tool.
- `git diff --check` passed.
- Read the entry point and all bundled references to check for
conflicting reporting instructions.
- This change edits skill instructions only. Repo-wide typecheck,
runtime tests, and build were not run locally.
- [PR
CI](https://github.com/paperclipai/paperclip/actions/runs/39253050703)
passed on head `d0b68db878fa4da83858da5f74fd25e6120723b5`, including
typecheck, test suites, build, and E2E checks.
- Greptile reviewed that head at 5/5 with no open findings.

## Risks

- Evidence must remain accessible in the task and PR. The instructions
still require decisions, keepers, commands, results, and limitations.
- An installed copy needs a refresh to receive this source change. An
operator can also apply the rule in the agent and routine instructions
immediately.

> 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-6. The exact runtime model ID and
context-window size were not exposed. Used repository search,
instruction editing, and shell validation.

## 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 (skill validation; no
runtime changes)
- [x] I have added or updated tests where applicable (not applicable to
this instruction edit)
- [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>
canary/v2026.1019.0-canary.4
2026-10-19 07:44:47 -05:00
Dotta c6a0cf4bce test(server): retire duplicated resolveShell darwin fallback row (#16639)
<!-- Write all pull request text in Simplified Technical English
(ASD-STE100): short sentences, one instruction per sentence, simple
approved vocabulary, and the active voice. -->

## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - The server prepares task workspaces in `workspace-runtime.ts`. One
helper, `resolveShell()`, picks the shell that workspace commands use.
> - `resolveShell()` computes its fallback with one two-arm ternary:
`"sh"` for win32, else `"/bin/sh"`. There is no separate darwin arm.
> - The tests for this helper had three unset-SHELL fallback rows:
linux, win32, and darwin. The darwin row repeated the linux row. It
observed the same ternary arm and asserted the same value through the
same code.
> - This pull request removes the duplicated darwin row. The linux row
keeps the non-win32 arm pinned.
> - The benefit is one less repeated registration per suite run and a
smaller platform matrix to maintain. No wall-time saving is claimed.

## Linked Issues or Issue Description

- No public GitHub issue exists for this cleanup. The underlying
problem: the `resolveShell` fallback tests registered two cases that
could not fail separately. Any change to the non-win32 fallback arm
breaks both rows at the same assertion. One row is enough to protect
that arm. The audit receipt in
`doc/plans/2026-10-17-workspace-runtime-resolveshell-test-audit.md`
records the full decision table, the deferred candidate, and the
retained rows.

## What Changed

- Deleted `falls back to /bin/sh on darwin when SHELL is unset` from the
`resolveShell (shell fallback)` describe in
`server/src/__tests__/workspace-runtime.test.ts` (6 test lines).
- Kept the win32 row (the only observation of the `"sh"` arm), the linux
row (the only needed observation of the `"/bin/sh"` arm), the
empty-string and whitespace-only rows (missing versus invalid input;
whitespace-only also pins the trim-before-check order), and the
missing-absolute-path row (the only observation of the `existsSync`
guard).
- Added the audit receipt
`doc/plans/2026-10-17-workspace-runtime-resolveshell-test-audit.md` with
evidence, commands, and the deferred candidate.
- Corrected the receipt's mutation-control record (head d99284b): the
`/bin/bash` control fails three retained rows, not one. See
Verification.
- Changed zero production lines, zero lockfile lines, and zero workflow
lines.

## Verification

- Focused owner run: `pnpm --filter @paperclipai/server exec vitest run
-t "shell fallback" src/__tests__/workspace-runtime.test.ts` (vitest
5.0.3, Node 25.9.0).
- Baseline before the edit: 9/9 passed.
- Candidate after the edit: 8/8 passed.
- Control (re-verified on head d99284b): the production fallback arm was
temporarily changed to `"/bin/bash"`. Exactly three retained rows then
failed with the same assertion (`expected '/bin/bash' to be '/bin/sh'`):
the linux unset row (the deleted darwin row's keeper), the empty-`SHELL`
row, and the missing-absolute-path row. The win32 rows and the
set-`SHELL` rows still passed (3 failed, 5 passed). This proves the
retained row carries the deleted row's failure sensitivity, and the
shared fallback value keeps two more independent guards. Production was
restored byte-exact (sha256
`335fd5332b4242ab0ff2a565323e27db48a69ddfb7bbd8d913e5148f79ff961b`
before and after), and the focused run passed 8/8 again.
- The full `workspace-runtime.test.ts` suite and the repo-wide
typecheck/test/build were not run locally; the isolated container cannot
finish the git-fixture cases inside their 15-second budgets (three
unrelated reconciliation cases time out at 15,000 ms on this host both
before and after the change). PR CI runs those lanes.
- PR CI on head d99284b: all 57 checks green (workflow run 39022073948;
the only non-success conclusions are conditional skips).

## Risks

- Low risk. The change is a six-line deletion inside one describe block,
plus a receipt correction. The only theoretical loss is a
darwin-specific fallback change, which does not exist today: darwin and
linux share the single non-win32 ternary arm. If a darwin-specific arm
is added later, that arm needs its own row and its own contract
decision.
- Open PRs #12658, #11753, and #16213 also touch
`server/src/__tests__/workspace-runtime.test.ts`, in different regions
(pnpm provisioning case, restart scoping, and worktree lock work). This
change edits only the `resolveShell` describe, so the hunks do not
collide.

> 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 be redirected — check the roadmap first. See
[`CONTRIBUTING.md`](CONTRIBUTING.md).

## Model Used

- GLM, a large language model from Z.ai. Exact model ID: `z-ai/glm-5.3`
served through OpenRouter (`openrouter/z-ai/glm-5.3`). Context window:
the session that produced this change. Capabilities used: repository
file search and read, shell command execution, vitest runs, and a
production mutation control. No model context-window size beyond the
session is asserted because it was not disclosed to the agent.

## 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
- [ ] 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-10-19 07:28:35 -05:00
DottaandPaperclip 1d24bd8e47 docs(skills): add fix-failed-paperclip-run workflow (#16830)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Failed or stalled tasks need a repair that restores useful work
without weakening execution safety.
> - The existing diagnosis skill stops at a plan and relies on private
historical task links.
> - A repair can pass a narrow test while still failing in the deployed
runtime or permitting duplicate work.
> - This PR adds a task repair workflow with
failing-before/passing-after evidence, safety tests, real workflow
verification, and PR checks.
> - The old skill name remains usable and preserves explicit
diagnosis-only or caller approval limits.

## Linked Issues or Issue Description

**Issue type**

Outdated documentation.

**Where is the issue?**

`.agents/skills/diagnose-why-work-stopped/SKILL.md`.

**What's wrong?**

The skill requires a plan approval even when implementation is
authorized. Its private task links do not provide usable guidance to
other contributors. It does not carry a repair through regression proof,
second-order checks, real workflow verification, and a green PR.

**Suggested fix**

Add `fix-failed-paperclip-run` and route the old name to it. Keep the
failure patterns self-contained. Keep explicit diagnosis-only requests
and the Terminal-Bench caller's approval boundary effective.

Related: #7658 established the maintainer skill location. A search for
the old and new skill names found no competing task-repair skill PR.

## What Changed

- Added a workflow from incident evidence through a verified repair and
current-head PR checks.
- Added eight standalone failure patterns with behavioral test oracles
and common verification traps.
- Replaced the old plan-only workflow with a compatibility entry point.
Preserved issue-tree classification and the three liveness invariants.
- Distinguished PR readiness, deployment, and recovery of the original
task. Reuse an existing sufficient fix instead of creating a duplicate
patch.

## Verification

- Rename commit `b979b632ee8f1ef57f1e7d6c37c711d1c83f5844`: both skill
validators, local reference checks, and whitespace checks pass. CI and
review are pending for this commit.

- The standard skill validator passes for both skill entry points.
- All Markdown references resolve. Referenced repository workflows
exist. The new files contain no historical task IDs, private URLs, or
machine-specific paths.
- `git diff --check` passes.
- Manually reviewed scenarios for an existing merged fix, unknown
historical cause, unsafe duplicate execution, live-only failure,
explicit diagnosis-only scope, and the Terminal-Bench approval boundary.
This is instruction review, not a live agent evaluation.
- Attempted `pnpm -r typecheck`, `pnpm test:run`, and `pnpm build`. All
stopped before execution because pnpm could not fetch and verify the
pinned version in the sandbox. This worktree also has no installed
repository dependencies. No runtime pass is claimed from these attempts.
- No product code changed. At head
`90ee31270420d2dac20dc3a41b12cddb5134d6ec`, 55 PR checks passed and 2
were skipped. Typecheck, tests, build, and the aggregate verification
gate passed in CI. Greptile is 5/5 with no inline findings or unresolved
review threads.

## Risks

- The old skill now continues into implementation when a fix is
authorized. Its explicit scope rule preserves diagnosis-only requests
and approval requirements from callers.
- This change is workflow guidance. Structural validation and scenario
review do not prove how a future agent will execute it on a live
incident.

## Model Used

OpenAI Codex, `gpt-6-astra`, with tool-assisted history inspection,
repository review, and Markdown authoring. The context window size is
not exposed in this session.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass (skill validation;
repository-wide commands could not start, as noted above)
- [x] I have added or updated tests where applicable (no runtime
behavior changed)
- [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-19 07:27:26 -05:00
DottaandPaperclip 6e89919631 refactor(storybook): check recovery disclosure visibility (#16828)
## Thinking Path

> - Paperclip helps people manage AI agents and their work.
> - Recovery previews show when work can continue and when an operator
must inspect it.
> - Saved-source reconstruction keeps its inputs inside a closed
disclosure.
> - The browser query can find those mounted inputs while the disclosure
is closed.
> - The old assertion required the inputs to be absent and failed before
testing the disclosure.
> - This pull request checks that each input is hidden, then keeps the
existing open-and-inspect assertions.

## Linked Issues or Issue Description

Refs #16686.

The `SourceReconstruction` story fails with “Found multiple elements
with the role textbox” while its disclosure is closed. The inputs are
mounted but hidden. Their visibility is the intended contract.

## What Changed

- Assert that all reconstruction text fields are hidden before opening
the disclosure.
- Keep the checks for the saved attachment and the disabled continuation
button after opening it.

## Verification

- Baseline: the browser play function failed at `queryByRole("textbox")`
because it found two hidden fields.
- Treatment: the same story passes all six browser interaction steps.
Both hidden-field checks execute before the disclosure opens.
- All ten play-enabled recovery notice stories pass in the browser,
including automatic recovery, operator and reader blockers, missed
recovery, read failure, mobile, reconstruction, and queued continuation.
Revisiting automatic recovery after the error and reconstruction
fixtures also passes.
- Catalog validation passes. All 28 map and catalog tests pass.
- UI typecheck and token gates pass. All 57 current-head checks pass or
have their expected skipped state, including workspace typecheck, tests,
and build.
- Greptile scored this head 5/5 with no unresolved threads. The initial
description gate did not recognize Storybook play files as tests; the
assertion-only change is classified as a refactor and its rerun passed.
- These stories use production components with fixture data. They do not
prove provider recovery or a production deployment.

## Risks

Low risk. This changes one Storybook assertion. A regression that
exposes a reconstruction field before opening the disclosure still fails
the visibility check.

## Model Used

OpenAI Codex, `gpt-6.1-sol`, xhigh reasoning, with tool use and code
execution. The host does not expose the 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-10-19 06:57:56 -05:00
DottaandPaperclip 51c81d0129 feat(sentry): link run errors to task and run pages (#16803)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Operators use Sentry to inspect run and server failures.
> - Reports identify the run and task, but the existing links open API
records.
> - Operators need a direct path from an error to the normal task and
run pages.
> - This change adds navigation links through the shared server Sentry
hook.
> - Saved company and task records determine the links. A failed lookup
preserves the error report.

## Linked Issues or Issue Description

Related work: #16300 added saved run API references.

**What existing behavior does this improve?**

Sentry event context for run failures, Stop timeouts, and server errors
from an authenticated agent run.

**Current behavior**

Reports show task and run UUIDs. The existing run URL opens an API
record. The operator must find the normal task page separately.

**Proposed behavior**

Add `task_url`, `run_url`, and `task_identifier` tags when saved run
metadata is available. Add `taskUrl` and `runPageUrl` to the event
context. Use the company prefix and saved task identifier in normal
board URLs.

**Reason and benefit**

An operator can open the task or run directly from the error report.

## What Changed

- Add a shared Sentry hook for events with a known run identity.
- Read only the saved company prefix, task identifier, and run identity.
Keep the lookup within the recorded company and agent.
- Include authenticated run identity on request errors. Use the existing
run identity on Stop errors.
- Bound optional lookups to one second and eight unfinished reads.
Preserve the original event on failure.
- Keep the existing API references and error grouping.
- Document the fields and add SDK, timeout, and company-boundary
coverage.

## Verification

- Passed: `pnpm -r typecheck` and the final server TypeScript check.
- Passed: `pnpm build`.
- Passed: 332 tests across the affected server suites, plus 25 final
link and real Sentry SDK tests after review fixes. The SDK test checks
outgoing event envelopes for run failures, request errors, and Stop
errors. It checks that unrelated errors receive no links. The database
test verifies saved metadata and company boundaries. It passes with
embedded PostgreSQL and with an explicitly configured disposable test
database.
- Passed in CI on `bec0cdac853efdef71041d59a66261941827653e`: the full
test matrix, typecheck, build, Runner checks, browser suites, and the
real Sentry SDK contract. All 56 active checks pass. Two Storybook jobs
are skipped.
- The full local `pnpm test:run` attempt first failed because PostgreSQL
library links were missing. The package setup script repaired the
install. The affected database suites then passed. The repaired full
local run was stopped after all CI test jobs passed; it did not complete
locally.
- Greptile: 5/5 on the final commit. All three review threads are
resolved.
- Read-only browser inspection confirms that Sentry displays context URL
values with an Open link control.
- No live test event was posted. Validation uses the real SDK with an
in-memory transport.

## Risks

- A slow or unavailable database can prevent optional links. It does not
discard the error. At most eight unfinished lookups can remain active.
- Missing or unsafe public origins omit the links. URLs longer than the
tag limit remain in context.
- This change applies to newly captured events. It does not update
existing Sentry events.
- The change adds no schema, permission, or first-party Telemetry
contract change.

## Model Used

OpenAI Codex, `gpt-6.1-sol`, xhigh reasoning, with tool use and code
execution. The exact context window is not exposed in the session
metadata.

## 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>
canary/v2026.1019.0-canary.3
2026-10-19 06:47:47 -05:00
Devin FoleyandPaperclip 2f6ad2226a fix(heartbeat): reconcile stranded running agent status (#16791)
Serialize agent completion status updates with new execution starts. Repair stranded running flags through existing recovery after durable work and cleanup settle. Share exact failed-lease cleanup proof with idle sleep, bound recovery work, and keep repair failures from blocking unrelated recovery.

Verified with 54 successful CI checks, 292 affected regressions after review fixes, workspace typecheck/build, and Greptile Apex 5/5 with no unresolved comments on the merged head.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
canary/v2026.1019.0-canary.2 nightly/v2026.1019.0-nightly.0
2026-10-18 22:20:41 -07:00
DottaandPaperclip 1a79c8bdc7 fix(runtime): honor provider startup budgets on sandbox resume (#16802)
## Thinking Path

> - Paperclip manages AI agents and their execution environments.
> - Follow-up runs reuse saved sandbox computers to keep their
workspace.
> - Starting a stopped or archived computer can take more than one
minute.
> - Acquisition already uses the provider's startup budget, but reuse
imposed a separate one-minute deadline.
> - This pull request gives resume the configured or declared provider
startup budget.
> - The benefit is that a healthy slow start can continue on the same
computer.

## Linked Issues or Issue Description

**What happened?**

A follow-up run failed during setup with `ReusableSandboxResumeError`.
The saved computer became ready just after the host stopped waiting. The
environment had no explicit timeout. Its provider declared a five-minute
startup default, which the resume path ignored.

**Expected behavior**

Resume must honor the configured startup budget or the provider's
declared default. It must retain the same lease. Failed or uncertain
resumes must keep the saved computer.

**Steps to reproduce**

1. Use a reusable sandbox provider with a startup budget longer than one
minute.
2. Retain its lease and start a follow-up run.
3. Make provider resume finish after 61 seconds, within that budget.
4. Observe that the old host rejects at 60 seconds.

**Paperclip version or commit**

Reproduced on `aaeff418cf72341c674ff3393cd94f40dc4855f6`.

**Deployment mode**

Hosted sandbox execution. The regression uses a local isolated
PostgreSQL database and controlled worker RPC timers.

Searched open and closed PRs and open issues for sandbox resume and
timeout fixes. No duplicate fix was found. Related acquisition timeout
handling already exists on the base branch.

## What Changed

- Use the provider's declared acquisition timeout when no explicit
startup timeout exists.
- Apply the resolved RPC budget to the shared resume/retry deadline
instead of 60 seconds.
- Add two deterministic 61-second resume regressions for declared and
explicit startup budgets. Assert exact RPC budgets, including the
30-second margin, and check that the same lease remains active without
replacement.
- Document the timeout behavior, provider-author contract, and
verification recipe.

## Verification

- Red: both new cases failed before the production change with
`ReusableSandboxResumeError`, caused by `Plugin RPC timed out`.
- Green: `pnpm exec vitest run --fsModuleCache
server/src/__tests__/environment-runtime.test.ts` passed all 163 cases.
The final review follow-up also passed both slow-resume cases with exact
RPC-budget assertions (330 seconds by declaration; 150 seconds by
explicit config).
- An earlier full run passed the 161 existing cases but timed out in the
two new tests because their fake clock also captured database
scheduling. The corrected test restores real timers before lease
persistence. The complete rerun then passed.
- `node scripts/check-maps.mjs` passed.
- `pnpm -r typecheck` and `pnpm build` passed locally.
- Started `pnpm test:run`, then stopped the duplicate serial run in
favor of complete parallel PR CI. The repository timing data totals
about 126 minutes for server suites alone. Full parallel CI passed on
the final head.
- CI attempt 1 had one unrelated failure:
`FileViewerSheet.copy.test.tsx` expected the asynchronous `Copied link`
confirmation before React rendered it. That test and component are
unchanged from the base branch. All six cases passed unchanged locally.
A single rerun of the failed shard passed; attempt 2 of the full
workflow succeeded. The timing-race diagnosis is an inference from the
test helper, not a claim that this PR repairs that UI test.
- Greptile scored the final head 5/5. Both review findings are fixed and
both threads are resolved.
- The consequential assumption is that provider startup may exceed one
minute. The test preserves the RPC timeout race with controlled timers
and uses real lease persistence. Read-only provider evidence also showed
the retained computer ready just after the failed run ended. The patch
has not been deployed to that instance.

## Risks

- A slow or unavailable provider may hold setup for its configured
startup budget instead of one minute. Retries still share one finite
deadline. Providers with no explicit or declared timeout keep the
one-minute default.
- Lease identity, company scope, backup validation, and replacement
decisions use the existing paths. No schema or dependency changes are
required.

## Model Used

- OpenAI Codex, GPT-6. This session supports reasoning, tool use, code
editing, and test execution. The exact runtime variant and
context-window size are not exposed.

## 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-18 22:04:23 -05:00
DottaandPaperclip b85a69b334 test(server): record observer load in native event replay (#16800)
Record observers and polling in synthetic native replay measurements, with zero-viewer controls and correctness checks.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-18 21:58:32 -05:00
DottaandPaperclip 3858d2341d fix(recovery): default saved-monitor waits and keep task recovery quiet (#16686)
## Thinking Path

> - Paperclip manages AI agents and their work.
> - A task must keep a durable path to its next action.
> - A provider can save a task monitor, then fail to yield because it
omits internal continuation fields.
> - An interrupted provider-pack check can then be reported as permanent
artifact incompatibility.
> - The task asks its user to certify recovered workspace files, even
though this is an operator responsibility.
> - This pull request derives the saved monitor continuation, bounds
verification retries, and removes that task form.
> - Normal recovery stays quiet. Unresolved holds retain inspection and
the existing safety checks.

## Linked Issues or Issue Description

**What happened?**

A yielded completion without `continuation` is rejected even after the
provider saves an eligible monitor on the task. Repeated attempts cannot
finish. Remote verification also treats timeouts and missing exit status
as artifact incompatibility. The task recovery notice exposes raw
diagnostics and asks the task user to certify infrastructure files.

**Expected behavior**

Use current persisted task state to fill routine continuation fields.
Retry interrupted verification reads within a fixed bound. Keep normal
recovery in the working state. Show a compact notice only when work
cannot safely continue.

**Steps to reproduce**

1. Save an eligible monitor on the active task.
2. Call `paperclip_finish` with `reportedWorkDisposition: "yielded"` and
omit `continuation`.
3. Return a timed-out remote provider-pack command with empty stderr
during recovery. Inspect the resulting task notice.

**Paperclip version or commit**

Source baseline: `aaeff418cf` (master integrated with its current task
visibility and saved-source reconstruction rules).

Related changes: #15824, #16104, #16451, #16493, #16690. This fix
complements saved-result recovery and verified pack reuse. It does not
replace their workspace ownership checks.

## What Changed

- Allow omitted or null continuation at the provider input boundary.
Read current authorized task context and fill a monitor continuation
only for the bound run and an eligible saved monitor. Keep accepted
results strict. Apply this to Codex, OpenCode, both direct and
production-sidecar ACPX paths, and external drivers. Reserve the
semantic call identity during the saved-context read and reject
cancellation or a changed run/turn.
- Bind the shared completion change and continuation helper in a new
Copilot v21 source declaration. Preserve v20 history and its decoder
support. Qualification stays pending.
- Expose the eligible continuation in task context. Completion admission
still checks persisted monitor state. No schedule is created or renewed
by the default.
- Retry read-only provider verification at most twice per command. Hold
exhausted reads with a distinct verification-unavailable cause.
Reattachment cannot renew the read budget through an unchanged
provider-attempt counter. Keep completed verification failures and wrong
versions incompatible.
- Remove the task file-certification form. Hide the notice only for a
matching durable recovery path without an unknown-action replay hold.
Keep missed retries, unsafe outcomes, and unresolved file holds visible.
- Add production-component stories for automatic recovery, blocked and
expired holds, reader access, persisted repair decisions, source
reconstruction, queued continuation, and mobile. Preserve master’s
guarded saved-source reconstruction choice after confirmed source
destruction. Update the execution contract and access maps.

## Verification

- Completion, helper, Codex, OpenCode, ACPX, and profile regressions
pass. After the sidecar review fix, 271 tests across the production
sidecar and three provider suites pass, plus 72 helper/profile tests.
The real sidecar MCP bridge tests cover saved-monitor acceptance,
no-monitor refusal, cancellation, duplicate call identity, and
raw-versus-forwarded semantic receipt hashes. The OpenCode tests also
cover eligible-monitor acceptance and refusal without one.
- The fresh full native executor suite passes all 743 tests. Four
profile, installation-integrity, and ACPX driver suites pass all 168
tests. The earlier CI fingerprint failure required a new immutable
source declaration; its follow-up Docker failure required the matching
context allowlist entry. Both fixes are verified locally. Targeted
server monitor, tool authority, and provider verification suites pass.
The probe tests include a real timed-out subprocess, an unrelated
responsive timer, transport errors, and completed integrity rejections.
- All 90 tests in the merged task notice, reconstruction choice,
recovery display, and lineage suites pass. They cover reader access,
live/missed/mismatched recovery, unknown outcomes, saved messages, retry
refusal, and removal of the file form. Both review findings have
failing-baseline/passing-treatment regressions: identical polling across
retry expiry, and a failed refresh after cached running activity.
- Browser walkthrough passed for automatic recovery, unresolved details,
a 390px mobile story, and the merged saved-source reconstruction and
queued states. The reconstruction control starts disabled and normal
automatic recovery shows only Working. The stories use production
components and fixture API data. They do not prove live cloud recovery.
- Token gates, map checks, and Storybook catalog generation pass. The
exact Docker context integrity command passes locally after adding the
new build declaration to its allowlist.
- Workspace typecheck and build pass on the final source, including the
versioned identity update. The final server and UI guards pass their
focused tests, typechecks, builds, and token gates. The final standalone
Storybook builds. The saved-monitor default retains master’s stricter
child-task visibility filter. Re-review caught an additional
production-sidecar validator before forwarding; the fix now defaults at
that boundary and has passing regression controls. After preserving
master’s new reconstruction capability, 68 targeted reconstruction,
tool-authority, and provider-verification server tests pass. The
current-master integration at `2a80050a0d` has a fresh 5/5 review with
zero unresolved threads. Its complete CI matrix, including Runner tests,
is the merge acceptance record.
- On the final master integration, local typecheck, build, and all 90
recovery UI tests pass. A concurrent runner run hit five 5-second
sidecar startup timeouts; an isolated sidecar run passed 86 tests and
timed out in the unrelated unsupported-bootstrap case. Those local
deadline failures remain recorded; the canonical CI Runner lanes use
their normal deadlines and pass. The unsharded local full-suite attempt
did not complete. It spanned source edits; the fresh native executor run
above passes. An unrelated workspace fixture timed out once and then
failed to reserve 32 contiguous ports on this host. Its unchanged-base
control and CI server suite pass. Full-suite acceptance uses the fresh
latest-head CI matrix; this PR does not claim a passing unsharded local
run.

## Risks

The default applies only to an eligible persisted monitor. An explicit
invalid continuation still fails validation. The added read occurs only
when a yielded report omits its continuation. Admission rechecks current
state after that read.

An interrupted verification command can add one extra 30-second probe.
Completed rejections stay closed. These probes do not change the pack,
launch provider work, or replay external tools. Two inconclusive reads
hold the original run. They do not schedule another reattachment with an
unchanged provider-attempt counter.

This PR’s pending Copilot v21 declaration binds the changed shared
contract, resolver, direct driver, and production sidecar sources. The
previous v20 declaration is immutable and remains decodable, but launch
requires the new exact identity. Qualification remains pending.

Task users lose the file-certification form. Board-authorized
source-only repair remains available through the resolution API with the
original evidence and stop-receipt requirements. This branch does not
deploy or recover historical held runs.

> This is a bug fix and UI polish within existing recovery behavior.
ROADMAP.md was checked.

## Model Used

OpenAI Codex, `gpt-6.1-sol`, xhigh reasoning, with tool use and code
execution. The host does not expose the 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 (changed-area suites; the
full 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-10-18 21:43:15 -05:00
DottaandPaperclip ad9f5edd49 docs: teach readable trace waterfall design (#16798)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Operators use traces to find slow work and explain task execution.
> - The Honeycomb skill explains how to find traces and add spans.
> - It gives little guidance on how a trace should read when its
branches collapse.
> - This pull request adds semantic grouping and lifecycle ownership
guidance.
> - The benefit is a clear overview that preserves useful detail for
diagnosis.

## Linked Issues or Issue Description

Related work: Refs #16453, which added this skill. Refs #16419, which
added execution preparation and response spans.

**Issue type**
Missing documentation.

**Where is the issue?**
The Honeycomb tracing skill under `.agents/skills/honeycomb-tracing/`.

**What's wrong?**
A trace can contain accurate timings but remain hard to read when most
spans share one parent. Local tests can also miss incorrect parentage in
exported traces, especially on failure.

**Suggested fix**
Explain how to group operations by purpose, preserve real parent
contexts, and inspect both collapsed and expanded exported traces. Keep
the current Observability contract as the source for exact span names
and root boundaries.

## What Changed

- Add trace design to the skill description and task routing.
- Define readable phases, meaningful folds, and real parent contexts.
- Add a reference with staging examples, failure and concurrency
pitfalls, and checks for exported traces.
- Preserve useful measurements and documented links between separate
lifecycles.
- Update the skill's display description.

## Verification

- Passed the skill creator's `quick_validate.py` check.
- Checked local Markdown references and skill metadata.
- Passed `git diff --check` after rebase onto current master.
- All 55 current-head GitHub checks passed. This includes application
build, TypeScript and Rust checks, general and serialized tests, runner
checks, browser E2E shards, and canary packaging.
- Greptile scored commit `714560594b69fb08afe7eb9fff42afef4a38e49a` at
5/5. It found no actionable issues. There are no unresolved review
threads.
- Local skill validation, reference checks, metadata checks, and
whitespace checks passed. The full local application checks did not
finish: the cold native runner build was stopped after the full CI suite
passed. Full application verification was completed in CI.

## Risks

Low risk. This change updates skill instructions only. An agent could
apply an example tree too rigidly. The reference states that examples do
not replace the current Observability contract. It preserves documented
linked roots and scope limits for verification.

## Model Used

OpenAI `gpt-6.1-sol`, with `xhigh` reasoning. Codex used local tools to
inspect session evidence, edit Markdown and YAML, and run validation.
The host does not expose the context window size.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass (skill validation,
references, and metadata; application checks passed in CI)
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] All Paperclip CI gates are green
- [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-18 21:37:40 -05:00
DottaandPaperclip 023f4a5d0c fix: preserve repository cache negotiation refs (#16687)
## Thinking Path

> - Paperclip manages agent work and its execution environments.
> - A fresh repository task needs an independent checkout before its
runner can start.
> - The object cache from #16487 should reduce repeated network
transfer.
> - The cache kept Git objects but dropped remote-tracking refs during
its bare clone.
> - Git needs those tips to negotiate which objects it already has.
> - This pull request preserves the tips in a versioned mirror cache and
records explicit cache outcomes.
> - The benefit is less repeated transfer and clearer evidence when a
cache does not help.

## Linked Issues or Issue Description

Refs #16487 and #16454. No duplicate cache-negotiation fix was found in
the public PR search.

**What happened?**

A valid object cache could make a fresh clone slower. A controlled
staging probe took 45.87 seconds and received 184.39 MB even though the
reference already held the objects. An earlier probe took 52.33 seconds.
An uncached clone took 20.94 seconds.

`git clone --bare` copied the pristine checkout's objects, local
branches, and tags, but omitted its remote-tracking refs. The source had
about 1,200 remote branches. Git could not use the missing tips to
negotiate those objects.

**Expected behavior**

Keep the pristine reference's negotiation tips. Each task must still
authenticate online, use the current remote refs, and end with
independent Git objects.

**Steps to reproduce**

1. Clone a repository with many remote branches into a fresh checkout.
2. Publish a reference with `git clone --bare --no-hardlinks` from that
checkout.
3. Clone the remote with `--reference-if-able` and `--dissociate`.
4. Compare with a reference that retains the remote-tracking tips. Use
Git Trace2 and count received pack bytes.

**Paperclip version or commit**

The staging runtime was `27ab902d3db2770ada79c9f42a9c06e1d346f34b`, with
Git 2.47.3. The cache implementation was unchanged from #16487.

**Deployment mode**

Docker on a persistent application volume. The probe used the
application file owner and the public Paperclip repository. It did not
start agent tasks or alter the application cache.

## What Changed

- Publish pristine object caches with `--mirror` to retain
remote-tracking tips.
- Put cache format version 2 in the key and receipt. The first checkout
builds a new generation. Existing generations stay under the current
storage limits.
- Keep the existing online authentication, current remote refs,
credential and company isolation, independent objects, quotas, and
fallback behavior.
- Add closed Honeycomb cache outcomes and a boolean that states whether
a reference was supplied to clone.
- Document that a lookup hit or supplied reference does not prove Git
avoided transfer.

## Verification

- Controlled staging component experiment: a disposable reference copy
held exactly the same 210,057 objects as the original. It added 1,187
advertised branch tips whose commits were already in those objects.
- Before: 45.87 seconds and 184.39 MB received, one sample in this
comparison.
- After: 12.20 and 14.58 seconds; median 13.39 seconds. Received pack
sizes were 1.99 and 1.95 MB.
- All comparison clones used the same current remote HEAD and ended
without an alternates file.
- The remaining repack took 9.72–9.81 seconds. Checkout file writing
took 0.86–0.96 seconds.
- The staging experiment restored tips on a disposable cache copy. It
did not deploy this patch or measure complete agent latency.
- Confirmed both staging scratch locations were empty afterward. The
original cache timestamps stayed unchanged. The temporary operator SSH
key was revoked and its local files removed.
- TypeScript 5.9.3 transpilation reported zero syntax diagnostics across
the four changed TypeScript files. `git diff --check` passed.
- The new negotiation regression fails with the old `--bare` publisher
and passes with the mirror publisher.
- Focused Vitest suites: 26 tests passed across repository-object-cache
and execution-preparation-timing. These cover independent objects,
current refs, unavailable/revoked remotes, scope separation, invalid
storage, tracing isolation, and endpoint-off behavior.
- The first full focused run passed 24 tests but failed its existing
localhost HTTP fixture because the sandbox denied `listen` on
`127.0.0.1`. The rerun with local loopback permission passed all 26
tests.
- Server semantic typechecking passed with `tsc -p server/tsconfig.json
--noEmit` after building the required workspace declarations. Initial
attempts lacked generated dependency outputs; the completed dependency
build and rerun passed.
- A full application build was not run locally. CI passed: 55 checks
passed and two optional checks were skipped. Greptile is 5/5 on the
current head, with both findings resolved.

## Risks

- Version 2 causes one cold cache rebuild. Old cache generations retain
their disk usage, and the existing quota can prevent publication.
- A cache still needs a full repack to produce an independent task
checkout. This PR does not remove that cost.
- The component experiment establishes the negotiation effect on
staging. It does not establish an end-to-end agent speedup or the
under-30-second goal.
- The new trace fields remain behind the existing OTLP gate. Their
values are closed enums or a boolean. They export no refs, paths, URLs,
cache keys, credentials, or error text.

## Model Used

OpenAI Codex, GPT-6 family, with code and tool use. The exact serving
model ID and context window are not exposed in this session.

## Checklist

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

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
canary/v2026.1019.0-canary.0
2026-10-18 21:28:20 -05:00
aaeff418cf fix(acpx): add a positive control to stalled-tool permission evidence (#16769)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - The ACPX engine runs Claude agents. A watchdog ends a turn when a
pending tool call gets no update for 30 minutes.
> - #16688 added a field to stalled runs. The field records if the
stalled call's permission request reached Paperclip.
> - Recent stalled runs show `acpStalledToolPermissionRequested: false`.
We can read this as "the call stopped before its permission request".
That reading is correct only if calls of the same kind usually send a
request.
> - We have no data that shows if finished calls of that kind sent
requests. Thus we cannot tell if the missing request is a real signal.
> - This pull request records a positive control: the number of finished
calls of the stalled call's kind, and how many of them sent a permission
request.
> - The benefit: the next stall event tells us if the missing request
locates the stall, or if it gives no information.

## Linked Issues or Issue Description

Refs #16688

**What happened?**
Runs stop with the stalled-tool watchdog error. The diagnostics show
that the stalled call sent no permission request. The diagnostics do not
show if finished calls of the same kind sent requests.

**Expected behavior**
The stalled-run diagnostics contain enough data to show if a missing
permission request is a real signal.

**Steps to reproduce**
A pending tool call gets no ACP update for 30 minutes. The watchdog ends
the turn. The run result contains the stalled-tool fields.

## What Changed

- `packages/adapter-utils/src/acpx-engine/execute.ts`: when the watchdog
fires, count the finished calls of the stalled call's kind, and count
how many of them sent a permission request. Write the counts to the run
result as `acpSettledSameKindToolCount` and
`acpSettledSameKindToolPermissionRequestedCount`.
- `server/src/services/run-failure-diagnostics.ts`: allow the two new
fields as non-negative safe integers. Other values are dropped.
- `doc/observability.md`: explain how to read the two fields with the
existing permission-request field.
- Tests: extend the existing stalled-tool tests in `execute.test.ts` and
`run-failure-diagnostics.test.ts`.

## Verification

- `pnpm exec vitest run src/acpx-engine/execute.test.ts` in
`packages/adapter-utils`: 244/244 pass.
- `pnpm exec vitest run
src/services/__tests__/run-failure-diagnostics.test.ts` in `server`:
115/115 pass.
- Mutation check: remove the kind filter, or count every finished call
as "requested". Each mutation makes the stalled-tool test fail.
- `tsc --noEmit` passes in `packages/adapter-utils` and in `server`.
Note: the full `server` `typecheck` script did not run locally, because
the runner vendor build step failed in this sandbox. I ran `tsc
--noEmit` directly.

## Risks

- Low risk. The change only adds two counts to the run result after the
watchdog fires. It does not change the decision to stop the turn, or any
permission decision.
- The fields hold only counts. They contain no tool titles, inputs, or
identifiers. This is the run-log and run-result path. It is not
Telemetry. The fields reach Sentry through the existing allowlist in
`run-failure-diagnostics.ts`.

## Model Used

- Claude Opus 5.5 (`claude-opus-5-5`), Anthropic, used through Claude
Code with tool use (shell, file edits, test runs).

## Checklist

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

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

---------

Co-authored-by: devinfoley <139239+devinfoley@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
canary/v2026.1018.0-canary.13
2026-10-18 13:59:16 -07:00
Devin FoleyandPaperclip 10d92eb468 fix(daytona): clear idle guard after verified sandbox cleanup (#16760)
Replace the lifetime provider-use guard with scoped allocation and pending-request evidence. Fence cleanup observations against overlapping work, retain timed-out raw requests, and wait for completed remote deletion before permitting idle sleep.

Verified with 436 Daytona tests, package and workspace typecheck/build, full CI, and Greptile Apex 5/5 on the reviewed head. Four deletion-boundary regressions and two concurrency regressions fail on the earlier implementation and pass with the fixes. Live-provider and local full-suite limits are documented in the PR.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-18 13:56:20 -07:00
Devin FoleyandPaperclip 1558d9962c fix(idle): exclude completed feedback history from background work (#16764)
Allow private feedback history and acknowledged uploads to stop blocking idle sleep. Pending, failed, unfamiliar, and inconsistent delivery records remain blocked; preserve all other work and cleanup gates.

Verified with 220 idle-safety tests, workspace typecheck/build, full CI, and Greptile Apex 5/5 on the reviewed head. Local full-suite limitations and isolated rechecks are documented in the PR.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-18 13:56:08 -07:00
Devin FoleyandPaperclip 5dced3c766 perf(tools): narrow profile and attention catalog reads (#16761)
Read only the catalog, connection, and invocation fields needed by profile summaries, reviews, and attention counts. Preserve company scope and response contents while reducing query payloads.

Verified with 445 affected service tests, workspace typecheck/build, full CI, and Greptile Apex 5/5 on the reviewed head. Local full-suite limitations and isolated rechecks are documented in the PR.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
canary/v2026.1018.0-canary.12
2026-10-18 13:56:04 -07:00
Devin FoleyandPaperclip 27709a99b1 perf(scripts): emit a server module beside the runtime bundle entry (#16765)
The runtime bundle now also has a server entry point, dist-runtime/server.mjs: the bundled dist/index.js without the argv shim. index.mjs loads it, so importing server.mjs loads the server code without starting it, and a compile cache warmed from it covers exactly the files a boot loads. bundleRuntime reports it as serverModule.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
canary/v2026.1018.0-canary.11
2026-10-18 12:16:13 -07:00
DottaandPaperclip c9669a6c22 docs(grok): record production qualification and Cloud setup (#16722)
## Thinking Path

> - Paperclip lets people manage AI agents and their work.
> - Grok Bot uses the shared Runner and an agent MCP connection.
> - The experimental Cloud release now passed real production setup and
work.
> - The setup guide does not list the Cloud opt-in controls or the
observed routine-panel workaround.
> - The readiness plan still describes the production rollout as
pending.
> - This pull request records the release evidence and the supported
setup path.

## Linked Issues or Issue Description

**Issue type**
Outdated documentation and missing setup instructions.

**Where is the issue?**
`doc/grok-bot-agent.md` and
`doc/plans/2026-10-13-grok-bot-production-readiness.md`.

**What's wrong?**
The guide starts after the opt-in step. The plan predates completed
production acceptance and the visibility rollout.

**Suggested fix**
List the three opt-ins and the Agents entry path. Record the exact
tested versions, rollout result and limits. Related runtime work:
[#16394](https://github.com/paperclipai/paperclip/pull/16394),
[#16444](https://github.com/paperclipai/paperclip/pull/16444),
[#16445](https://github.com/paperclipai/paperclip/pull/16445).

## What Changed

- Add the Cloud MCP, Runner and Grok opt-in steps.
- Explain the supported external-agent entry and the Grok Webhook-panel
link workaround.
- Record both tested production versions, assigned and proactive
results, cleanup, the 43-target rollout and a fresh-workspace check.
- Keep the historical failure and evidence limits explicit.

## Verification

- `git diff --check origin/master...HEAD` passed.
- Compared the report with saved production receipts, serving-version
observations, provider image digest, authenticated challenge, download
hashes and cleanup receipts.
- Real assigned work, question/answer, document/file delivery and
proactive work passed on Core
`4415665d67b16ffefbe4519c4bdd521f37bb87b9`.
- Current production source CI passed its required lanes. The collected
non-export checks contain 50 successes, 29 skips and no failures.
- A fresh Cloud workspace exposed the opt-ins, saved them after reload
and offered Grok in the external-agent picker. All test switches were
then restored to off.
- This change edits only Markdown. Runtime typecheck, tests, build,
token and Storybook checks were not rerun locally for this documentation
commit. The plan distinguishes earlier staging recovery proof from
current production tests.

## Risks

Low runtime risk. This change edits no source, schema, workflow or
feature setting. The report qualifies the named versions only. The
first-company model wizard still does not offer external agents. Grok
usage, spending and remote termination remain unknown.

## Model Used

OpenAI Codex, GPT-6 family, with reasoning, repository tools and
browser/native-app testing. The session does not expose the exact
deployed model ID or context-window size.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used, including the runtime metadata
that is available
- [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 applicable local documentation checks and they
pass; runtime tests were not rerun for Markdown-only edits
- [x] I have added or updated tests where applicable; no new tests apply
to these documentation edits
- [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 (55 passed; two optional
Storybook skips)
- [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>
canary/v2026.1018.0-canary.10
2026-10-18 07:15:53 -05:00
DottaandPaperclip 8de28c12e4 test(server): prove execution span overlap with explicit barriers (#16712)
Prove overlapping execution spans with per-run promise barriers, live recording checks, and exported span identity matching. Preserve the existing run ownership, parent, ingress-link, count, and test-budget assertions.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
canary/v2026.1018.0-canary.9
2026-10-18 03:00:21 -05:00
DottaandPaperclip bfadb66556 fix(daytona): retain already archived workspaces on stop (#16710)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Stop-only recovery must keep unfinished remote workspace files safe.
> - Daytona can archive a stopped sandbox while those files remain in
object storage.
> - The stop handler sent another Stop request for that archived source.
> - Daytona rejected that request, so recovery could not record its
required receipt.
> - This change accepts the freshly confirmed archived state after
retention is verified.
> - Recovery can proceed while the source stays cold and its files
remain available.

## Linked Issues or Issue Description

Refs: #16583, #16700.

**What happened?**

Stop-only cleanup rejected a retained workspace after Daytona archived
it. The live provider returned `DaytonaValidationError` for Stop while
its state was `archived` and auto-delete was already disabled. The host
correctly kept the recovery gate closed.

**Expected behavior**

Confirm the exact source and its retention policy. Treat an archived
source as having no running process. Record the stop-only receipt
without starting or deleting the source.

**Steps to reproduce**

1. Keep an unfinished native workspace with stop-and-retain intent.
2. Let its stopped Daytona sandbox become archived.
3. Request stop-only cleanup.
4. Observe the rejected Stop request and missing receipt.

## What Changed

- Accept `archived` after a fresh provider read confirms that
auto-delete is disabled.
- Stop the source if that fresh read instead shows it has resumed.
- Add regression cases for confirmed retention, unconfirmed retention,
and a resumed cached handle.
- Update the recovery runbook and capability map.

## Verification

- The new baseline fixture failed on the old handler: 1 failed, 2
passed.
- Daytona provider suites: 417 passed, 6 skipped.
- Full workspace `pnpm -r typecheck`: passed.
- Full workspace `pnpm build`: passed on `fc8b1c1bb8`.
- Maps and Git whitespace checks: passed.
- The live provider rejection was reproduced on the exact retained
source. No model turn, file change or delete was performed. The fixed
source handler was then run against that same archived allocation with
the declared SDK version. It returned the stopped-process receipt while
the provider stayed archived with auto-delete disabled. No process was
started. All 58 exact-head CI checks passed; independent review is 5/5.
A full local run is also in progress on a separate frozen checkout of
this revision; it is not reported as complete.
- [Daytona lifecycle
documentation](https://www.daytona.io/docs/en/sandboxes/) confirms that
archive follows Stop and preserves the filesystem in object storage.

## Risks

- An archived source grants a generic stopped-process receipt. Its
physical provider state stays archived.
- Retention confirmation remains required. A stale archived handle that
has resumed still requires Stop.
- The host still checks the original allocation, ownership, stop receipt
and file-recovery evidence before continuation.

## Model Used

OpenAI Codex, GPT-6 family, with reasoning, tool use and code execution.
The session does not expose an exact backend model ID or context-window
size.

## Checklist

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

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-10-18 02:50:49 -05:00
DottaandPaperclip 6bec153410 fix(runtime): retain cancelled workspaces before reconstruction (#16700)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Native runs must preserve files when Stop ends a turn before its
result is saved.
> - The cancellation path could skip file retention and leave a prepared
remote workspace active.
> - An older controller could also admit an extra run while an earlier
lost-source hold was unresolved.
> - Rejecting every later run then prevented recovery even after that
extra run was stopped and its files were reconciled.
> - This change retains cancelled workspaces and records the exact proof
for a safely reconciled intervening cancellation.
> - Recovery can proceed without changing cancelled history, replaying
actions, or weakening execution gates.

## Linked Issues or Issue Description

Refs: #16583, #16690, #16696.

**What happened?**

Stop could acknowledge a native turn without recording its unsaved file
obligation. Reconstruction also rejected a later cancelled run after its
exact environment and files had been reconciled. The task could remain
inactive with an `in_progress` status, which the reconstruction endpoint
rejected.

**Expected behavior**

Retain unsaved files after Stop. Permit a board operator to reconstruct
from saved sources only after each intervening cancellation has a
confirmed stop and a file-only repair record. Preserve the original
failed export and the cancelled run.

**Steps to reproduce**

1. Prepare a native workspace and cancel the turn before a structured
result exists.
2. Inspect its file retention and remote lease state.
3. For a task with an older destroyed export, reconcile the later
cancelled run's exact files and unperformed actions.
4. Request reconstruction from verified same-task attachments.

## What Changed

- Pin prepared native files before cancellation settlement. Defer
teardown if pinning fails. Use the existing stop-only cleanup worker.
- Repair active warm and ephemeral sources, plus stopping and
confirmed-stopped historical cancellations in bounded startup and
periodic batches. Preserve the existing exact-source checks. Bound
row-lock waits and advance past a busy source.
- Accept only same-owner native run-only cancellations with no result or
current coordinator, confirmed stopped leases, and board file-only
repair with `not_performed` action outcomes.
- Save hashes of each intervening repair and recheck them at queue claim
and final dispatch. Reject changed evidence or another later run.
- Expose saved-source reconstruction in the issue API for inactive
`blocked` and `in_progress` tasks, and hide it when an execution or
checkout owner exists. Permit the same inactive source at submission.
Keep the source, owner, version, attachment, budget, pause and retry
checks.
- Update the shared evidence type, recovery runbook and capability maps.
Add an optional cancelled-native no-action confirmation to file
recovery, resetting evidence when its source changes. No migration, new
endpoint, permission or dependency.

## Verification

- The new fixture fails on the original validator with
`workspace_reconstruction_stale` after valid cancelled-run file repair.
- Focused source and Stop retention tests: 94 passed before the final
contention case. The subsequent three-suite run passed 123 tests,
including real PostgreSQL lock contention and public
startup/API/final-dispatch paths. The final narrow-query rerun passed
all 123 tests. Review correction: all 143 tests passed across four
suites, including real lock contention through the teardown boundary and
stopping/stopped allocations.
- Six broader cancellation, executor, heartbeat and restart suites: 831
passed, 9 existing skips.
- Final correction: all 145 backend tests and all 36 recovery UI tests
passed. Real contention covers both warm reusable and ephemeral sources.
Optional no-action confirmation defaults to uncertified, and changing
source clears evidence. Workspace `pnpm -r typecheck` and token gates
passed on these sources.
- Maps, module boundaries and Git whitespace checks: passed. Full `pnpm
build` passed on the final `4e8c0e73ac` revision as well as the prior
reviewed heads. A full local run of the preceding fix completed with
21,724 passes, 109 skips and three failures in webhook body limits, a
status-card timeout, and a port-allocation fixture. All three suites
then passed unchanged in an isolated rerun (209 tests). The full local
run remains recorded as failed; the final head's full CI passed (55
completed checks, no failures). A fresh full local run is also in
progress on the frozen reviewed head.
- Preserved failures: the first attempt lacked a built plugin SDK; after
building prerequisites, the regression reached the expected validator
rejection. Treatment tests caught the file-only action's deliberately
null continuation owner. A real lock test then caught the database
driver's wrapped timeout error. Both defects were corrected and
retested. Independent review then found a teardown race after a failed
retention write. A second review found active warm sources excluded by
the historical policy filter; the regression reproduced both warm
failures before correcting the query. Its real-row-lock fixture
reproduced the failure; the fixed release guard and historical
stopping/stopped cases pass. No checks were weakened.
- A pre-deployment walkthrough caught the issue API still hiding
reconstruction for an inactive `in_progress` task. The status/capability
baseline reproduced three failures, including inappropriate capability
flags for execution/checkout owners. The fix uses the same
inactive-state requirements as submission; its positive fixture reads
the assembled issue API before reconstructing. All 117 tests in those
three recovery suites pass, and all 28 heartbeat-recovery tests pass
separately. Full workspace typecheck passed again. Full build passed
with the exact `4e8c0e73ac` stamp; latest-head independent review is 5/5
with no open findings. All 55 latest-head checks completed with no
failures.
- Live tenant acceptance remains pending. No successful reconstruction,
export or warm-process proof is claimed by these local tests.

## Risks

- Stop retains unfinished work, so storage remains until file recovery
and explicit cleanup complete.
- Reconstruction remains held for unknown or performed external actions,
foreign owners, live or rebound environments, accepted results, changed
evidence, and unrelated later runs.
- The sweep examines at most five candidates per pass. It uses a fair
cursor and bounded transaction waits. It performs no provider call and
starts no new turn.
- Intervening verification reads only the needed JSON fields. The source
transaction still serializes recovery for the same task.

## Model Used

OpenAI Codex, GPT-6 family, with reasoning, tool use and code execution.
The session does not expose an exact backend model ID or context-window
size.

## Checklist

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

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
nightly/v2026.1018.0-nightly.0 canary/v2026.1018.0-canary.7
2026-10-18 01:33:11 -05:00
5623304586 test(runner): isolate provider fixture targets and executables (#16701)
Scope the existing Grok and Pi fixture callbacks to their declared Linux x64
target, and restore the original process descriptors after each callback.
Keep OpenCode executable mode changes inside test-owned temporary copies.

Adapt the two-file OpenCode fixture isolation from caniko's PR #14580,
commit f329db3d6f. Extend the same isolation
to the remaining per-turn reasoning fixture. Preserve every existing test
assertion, case, skip and budget without changing provider support or pins.

Co-Authored-By: Can H. Tartanoglu <gpg@rotas.mozmail.com>
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-18 00:58:47 -05:00
DottaandPaperclip 39c345ec5c test(runner): bind Copilot pack fixture to a supported target (#16697)
Scope the Copilot candidate registry fixture to the supported Linux x64 target and restore both process property descriptors. Preserve every existing assertion and production provider pin. The five-case focused treatment and current PR CI passed; fresh review is 5/5.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
canary/v2026.1018.0-canary.6
2026-10-18 00:09:00 -05:00
DottaandPaperclip 69ac928d2b fix(runtime): preserve bounded retries after workspace reconstruction (#16696)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - An operator can rebuild a destroyed workspace from saved task
attachments.
> - The first reconstruction run must pass current source and execution
checks.
> - A temporary bootstrap failure can create a bounded retry before
provider work starts.
> - The retry has a new run ID, so the first-run-only reconstruction
check rejects it.
> - This change verifies the retry chain back to the approved first run
and keeps current safety checks.

## Linked Issues or Issue Description

Refs #16690.

**What happened?**

After an operator records workspace reconstruction, a safe bootstrap
retry is cancelled before provider startup. The normal retry scheduler
creates the successor. The reconstruction check then rejects its
immediate predecessor because it expects the original failed export run.

**Expected behavior**

A verified automatic retry can continue under the same reconstruction
decision and remaining retry budget. Changed sources, unrelated
executions, uncertain outcomes, pause and later human blocks must still
stop startup.

**Steps to reproduce**

Record reconstruction with a retry budget remaining. Let its first run
fail before provider work starts with recorded bootstrap evidence. Use
the normal bounded retry scheduler and the locked dispatch gate. Before
this change, the scheduler succeeds but dispatch returns false.

## What Changed

- Verify the predecessor chain back to the recovery action's exact first
continuation.
- Check company, task, agent, terminal predecessor state and each
scheduler-owned wake. Reject cycles, foreign parents and forged wakes.
- Exclude only those verified predecessors from the unrelated-newer-run
check. Keep source hashes, original result identity and all current
execution gates.
- Reuse the existing reconciliation proof for failed predecessors. Keep
the original retry limit.
- Add real PostgreSQL scheduler and assembled-heartbeat regressions.
Update the recovery guide and feature map.

## Verification

- The baseline regression failed at final dispatch after the normal
retry scheduler created its successor.
- The corrected focused group passes 133 tests across reconstruction,
retry scheduling and dispatch. It admits two bounded bootstrap retries
and refuses a third. The assembled heartbeat enters the provider once
for an eligible retry and zero times after a controlled post-claim human
block.
- An intermediate negative case exposed missing predecessor-outcome
validation. Reusing the existing reconciliation proof fixes it. Deleted
sources, pause, forged wakes, foreign parents, unrelated runs and new
recovery holds remain refused.
- Full workspace typecheck and build pass on rebased head
`bd301ec8a703fa1cdc9e1db2638440d203e8d57a`. The rebased focused group
passes all 133 tests. All CI gates pass on that exact head, including
general/serialized tests, Runner, build and browser gates. Greptile is
5/5 with no unresolved threads. A clean full local `pnpm test:run` is
running; the local source stays frozen for that run.
- Module boundaries, maps and diff whitespace checks pass. Live staging
acceptance follows the qualified full Cloud deployment.
- The earlier full local run for #16690 failed while files changed and
its PATH hid `lsof`. All five affected suites then passed in a clean
run: 246 passed, three skipped. Those results do not establish a full
local pass for this follow-up.

## Risks

- Retry ancestry is a rare recovery path. Its primary-key reads grow
with the chain and stop at 64 predecessors. Ordinary runs perform no new
ancestry reads.
- Unknown effects and active recovery obligations stay held. This does
not reset budgets, change provider lifecycle policy, grant access or
replay completed actions.
- No schema migration or new API is included.

## Model Used

OpenAI Codex, GPT-6 family, with reasoning, tool use and code execution.
The session does not expose an exact backend model ID or context-window
size.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass (focused checks; full-run
scope 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-10-17 23:48:28 -05:00
DottaandPaperclip 1678aae862 fix: expire unused bases with generated repository ignore metadata (#16695)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Finished tasks can release Git caches that Paperclip can restore
later.
> - Nested repository preparation adds an ignore entry to the base
repository.
> - Base cleanup currently treats this generated entry as custom
metadata.
> - This pull request accepts the exact generated entry and keeps other
metadata protected.
> - Unused private bases can then expire with their workspaces and
return on demand.

## Linked Issues or Issue Description

Refs #16691. Related #15404 and #14443 change repository preparation or
sync, not base expiration.

**What happened?**
A finished workspace with a nested project repository expires, but its
unused private base remains with `custom_git_metadata`. Normal
preparation added `/.paperclip-repositories/` to the stock Git exclude
file.

**Expected behavior**
Cleanup removes a verified, unused base with this generated entry.
Custom metadata still prevents base deletion.

**Steps to reproduce**
Create an isolated workspace with a nested repository through normal
preparation. Finish the task, wait for the retention period, and run
expiration. The workspace disappears but its private base remains.

**Paperclip version or commit**
790b729086.

## What Changed

- Accept stock `info/exclude` bytes or stock bytes plus the exact single
entry produced by Paperclip.
- Verify base deletion and restoration of both repository commits and
settings after upstream advances.
- Preserve custom patterns, comments, extra bytes, duplicate entries,
and symlinks.

## Verification

- Captured a failing lifecycle baseline: the workspace expired but the
base remained with `custom_git_metadata`.
- Both new real Git/PostgreSQL lifecycle cases pass. Restoration returns
main and nested commit A after upstream moves to B, preserves settings
permissions, and permits a subsequent commit.
- Six focused metadata controls pass. The retained baseline fixture
passes the storage check without edits to its files.
- Server typecheck passes. Full local build passes. Required CI is
tracked on this PR.
- Independent review found no actionable findings. Staging reclamation
and product reopening remain deployment acceptance checks.

## Risks

This expands a deletion allowlist. Matching is byte-exact and limited to
the generated suffix. Other ownership, authenticated fetch, consumer,
file, and Git history checks remain required. No schema or retention
changes.

## Model Used

OpenAI Codex (GPT-6), with code execution and independent agent 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
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [ ] All Paperclip CI gates are green
- [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-18 04:40:05 +00:00
DottaandPaperclip 2befcd9a0a Harden Board CLI approval and native verification fixtures (#16482)
Preserve governed Board CLI authority and strict verification fixtures on the Muse stack.

Keep approval/cancel ownership, current membership/key authority and durable first-change audit atomic. Bound Retry-After scheduling within the original challenge; never automatically resubmit consent. Retain descriptor ownership until identity-based cleanup and close it on success and error. Keep strict Git-origin and synchronized provider-entry fixture assertions.

Related public work: LukeAbell's existing PR #13919 proposes the same production descriptor-lifetime fix. This independently measured local integration retains the original tests and adds real-descriptor coverage. Do not treat this local integration as ownership of that contribution.

Carry actual merged UI source 896f3c7f3b through a normal forward merge, preserving canonical workspace recovery, Muse authority and existing migration bytes. Current-head CI and substantive review remain merge gates. Complete qualification of the final immutable canonical source and actual provider acceptance remain separate.

Refs #16482, #13919.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
canary/v2026.1018.0-canary.5
2026-10-17 23:22:57 -05:00
63306f6660 fix(acpx): record whether a stalled tool call's permission request arrived (#16688)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - Hosted `claude_local` runs use the ACPX engine. Claude can start
background subagents, and those subagents call the runtime MCP tools
that Paperclip attaches.
> - #16671 added a stalled-tool watchdog. It ends a Claude turn when a
pending tool call gets no ACP update for 30 minutes. That PR said the
most likely cause of the stall is a lost ACP permission round trip, but
it could not prove it.
> - A staging run tripped the watchdog. Two background subagents started
12 MCP calls. ACP reported each call as `pending`, and no call got
another update. The MCP gateway logs show the 9 earlier calls from the
parent agent, but no request from the 12 subagent calls.
`MCP_TOOL_TIMEOUT` (15 minutes) did not end them. So the calls stalled
before Claude sent them to the MCP server.
> - The run record cannot say if the permission request for a stalled
call reached Paperclip. Without that fact, the next stall gives no new
evidence about the cause.
> - This pull request records, for a stalled run, whether the stalled
call's permission request reached Paperclip, and how many pending calls
had a permission request.
> - The benefit is that the next stall tells us which side of the
permission round trip stopped, so the real fix can go to the correct
layer.

## Linked Issues or Issue Description

- Refs #16671 (the stalled-tool watchdog; this PR tests the cause that
PR suspected)
- Refs #16360 (the MCP client deadline that cannot reach a call that was
never sent)

**What happened?**

A hosted staging `claude_local` run started two background subagents.
Each subagent started six `execute-sentry-tool` MCP calls. ACP reported
all 12 calls as `pending`. None got a result, an update, or an error.
The MCP gateway received no request for them. The parent turn finished
its answer but stayed open for the subagents. After 31 minutes the
watchdog ended the turn with `acpx_tool_stalled`. A single background
subagent with six parallel calls to the same tool did not stall in a
later test.

**Expected behavior**

When a tool call stalls, the run record shows if the call's permission
request reached Paperclip. Then the stall can be put on the agent side
or on the relay side of the round trip.

**Steps to reproduce**

1. Start an ACP `claude_local` run in a sandbox that uses two background
subagents to call runtime MCP tools.
2. Wait until a subagent's tool calls stay `pending` with no further ACP
update (in staging this happened without a known trigger).
3. See that the watchdog fails the run with `acpx_tool_stalled`, but the
record has no evidence about the permission round trip.

**Paperclip version or commit**

`master` at 1f27427.

## What Changed

- The ACPX engine passes an `onPermissionRequest` hook to the ACPX
runtime. The hook records the tool call ID of each permission request
and returns `undefined`. ACPX then uses its permission mode to decide
the request, the same as before.
- When the watchdog fires, it records `permissionRequested` for the
stalled call and counts the pending calls that had a permission request.
- A stalled run's result has two new fields:
`acpStalledToolPermissionRequested` (boolean) and
`acpPendingToolPermissionRequestedCount` (non-negative integer). The
`[paperclip]` stderr line also says if the request reached Paperclip.
- The server run-failure diagnostics allowlist the two fields. They
accept only a boolean and a safe non-negative integer.
- `doc/observability.md` describes the fields. It also says that a
background subagent's Task call completes when the subagent starts, so
the watchdog watches the subagent's own calls.

## Verification

- `npx vitest run src/acpx-engine` in `packages/adapter-utils`: 21
files, 423 tests pass.
- Engine tests:
- The existing stall test now sends a permission request for the Task
call only. The run records `acpStalledToolPermissionRequested: false`
and a count of 1. The hook returns `undefined`. The log line says the
request did not reach Paperclip. No tool title or ID appears in the
diagnostics.
- A new test sends the permission request after the relay saw the
stalled call. The run records `acpStalledToolPermissionRequested: true`.
- Mutation check: when the hook does not record the ID, both tests fail.
- `npx vitest run
src/services/__tests__/run-failure-diagnostics.test.ts` in `server`: 115
tests pass. Invalid values for the new fields are dropped.
- `npx tsc --noEmit` passes in `packages/adapter-utils` and in `server`.
- Runtime dependency assumption: the hook must not change permission
decisions. I called the real patched `acpx@0.12.0`
`AcpClient.handlePermissionRequest` with and without the hook in
`approve-all`, `approve-reads` and `deny-all`. The responses and the
permission stats were the same in each mode, and the hook saw each
request. The hook only adds an ID to an in-memory set for the run, so it
adds no remote call and no blocking work.
- Limits: the tests mock the runtime, so they do not prove the hook runs
in a real sandbox relay. The acpx source passes the hook to the client
on every runtime path (`runtime.js`), and the real-client check above
covers the decision path.

## Risks

- Low risk. The hook only observes. If ACPX ever treats a host hook as
the decision owner, the check above would show a different decision.
That is not the case in the pinned `acpx@0.12.0`.
- The set holds one string per permission request for the length of one
run. That is bounded by the number of tool calls in the run.
- This PR does not fix the stall. It gives the evidence for the next
occurrence.

## Model Used

- Claude Opus 5.5 (`claude-opus-5-5`) through Claude Code, with tool use
and code execution. It read the run log, the gateway logs, and the ACP
agent and client code, ran reproduction probes, edited the code, and ran
the tests.

## Checklist

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

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

---------

Co-authored-by: devinfoley <139239+devinfoley@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 21:05:43 -07:00
DottaandPaperclip 896f3c7f3b Add personal Muse operator setup and composer controls (#16450)
Add Muse invitation, connection readiness and scoped operator controls.

Keep connection state tied to the current company, person, agent and binding. Surface failed reads and invalidate stale cleanup observations; require current authority and exact readback. Preserve Dot/Grok setup, source-trust limits and existing design tokens.

Carry actual merged backend e6dcc6b095 through a normal forward merge. Preserve its project-write authority fix, existing migration bytes and upstream idle-serving behavior; no new UI behavior is authored by this source carry. Current-head CI and substantive review remain merge gates; final canonical and deployed-provider qualification remain separate.

Refs #16450.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-17 23:01:42 -05:00
DottaandPaperclip 7c7d2d8d2c fix(runtime): continue from saved sources after workspace loss (#16690)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - The runtime must preserve saved work and prevent duplicate
execution.
> - Older cleanup could destroy a sandbox before its workspace export
finished.
> - The existing recovery controls require either the original sandbox
or recovered original files.
> - Surviving attachments can support a rebuild, but they do not prove
that missing edits were recovered.
> - This pull request adds an explicit reconstruction decision and one
fresh continuation through the normal execution gates.
> - Operators can continue useful work while the original failed run
remains truthful.

## Linked Issues or Issue Description

**What happened?**

A historical failed export can have an accepted result, a prepared
workspace descriptor, and a confirmed destroyed sandbox. Its notice can
also say `new_source_execution_path` and disappear. The task then has
neither a truthful original-file repair path nor a supported
reconstruction path.

**Expected behavior**

Keep the missing-file obligation visible. Let an authorized operator
choose surviving task attachments and record lost work and external
action outcomes. Start one fresh continuation after current execution
checks. Keep the old result and failed export intact.

**Steps to reproduce**

1. Seed a failed native export with a prepared descriptor and an exact
destroyed-lease receipt.
2. Resolve its notice with the historical `new_source_execution_path`
bookkeeping value.
3. Read the task. The baseline hides the hold even though no source
reconciliation exists.
4. With this change, choose **Continue from saved sources** and submit a
reconstruction decision.

Related public work: #16451 preserves healthy warm sessions. #16583
prevents destructive cleanup of unexported work. This change handles
historical source loss that those fixes cannot undo. Searches of open
and closed work found no equivalent reconstruction endpoint.

## What Changed

- Add a board-only reconstruction endpoint with `runtime:manage` and
task visibility checks.
- Validate the exact run, result, descriptor and destroyed lease. Reject
active copyback, competing owners, newer work, stale task status, and
foreign attachments.
- Record attachment hashes, missing work, and external action outcomes.
Preserve the original failed run, accepted result, prepared descriptor
and terminal failure.
- Hold other continuation paths until the durable reconstruction intent
admits its successor. Record that successor in the same transaction and
preserve the retry count.
- Add an operator control that distinguishes reconstruction from
original-file recovery. Update the recovery runbook and capability maps.

## Verification

- Exact baseline source returns no blocker for the destroyed-source
fixture. The same fixture returns a required recovery hold with this
change.
- New real PostgreSQL and assembled API/heartbeat suite: 25/25 pass. It
covers duplicate submissions, lost acknowledgement, context reset,
source identity, task ownership, concurrent execution attachment scope,
later human blocks, deleted sources and agent pause.
- Existing export retry, explicit continuation and recovery-action
suites: 386 cases pass. One new-fixture constraint error in the combined
run was corrected; the full new suite then passed.
- UI recovery suites: 46/46 pass across three files. They cover disabled
actions, loss acknowledgement, failure retention and runtime authority.
- `pnpm -r typecheck` and `pnpm build` pass. The first sandboxed
typecheck attempt could not open the TypeScript IPC socket; the
authorized rerun passed.
- Module boundaries, map checks, token gates and diff whitespace checks
pass.
- OpenAPI route coverage: 21/21 pass. The first CI head exposed a
missing endpoint registration; this head adds the registration and the
focused suite passes.
- Review identified a missing dispatch-time check and an isolated
attachment cache. Both are fixed. Claim and final handoff recheck the
exact successor, sources and current execution gates. A controlled
post-claim operator block prevents the assembled heartbeat from entering
the provider. The shared attachment cache refreshes uploads and removes
deleted selections.
- Final focused run: 180/180 pass across six suites, including
reconstruction, existing dispatch/stale-queue contracts and UI recovery.
- A second review reproduced cancellation by an already satisfied
historical connection card while the task was `todo`. Read-only
connection availability now works before checkout; active-task mutation
checks remain strict. The baseline failed two cases; after the fix all
74 connection and reconstruction tests pass, including revoked access,
pending questions and pending approvals.
- All current-head CI gates pass on
`9d197236da11fa24f1ceadf5589cb2b81179d824`, including general/serialized
tests, Runner, build and browser gates. Greptile is 5/5 for that exact
head with no unresolved threads. The full local `pnpm test:run` is still
running its serial server group; no full local pass is claimed. Live
staging recovery is pending deployment.

## Risks

- Reconstruction cannot restore missing bytes. The operator must
identify surviving sources and actions that must not be repeated. The
agent must verify those attachments before rebuilding.
- This path is limited to exact, confirmed destroyed remote sources with
an accepted result. Retained or uncertain sources keep their existing
repair path.
- No schema migration, credential change, budget increase or
warm-session policy change is included. Normal pause, ownership, budget,
approval and dispatch gates still apply.

## Model Used

OpenAI Codex, GPT-6 family, with reasoning, tool use and code execution.
The session does not expose an exact backend model ID or context-window
size.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass (focused suites; full local
run limitation 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-10-17 22:57:10 -05:00
DottaandPaperclip 790b729086 fix: restore nested project repositories and settings after expiration (#16691)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Agents use isolated Git workspaces with managed project repository
copies.
> - Finished workspaces can expire when Git can reproduce their
contents.
> - The saved recipe records the main commit but omits nested commits
and local settings.
> - Reopening can therefore use newer nested code and lose merged user
settings.
> - This pull request saves and restores those contents before workspace
provisioning.
> - It also permits verified FETCH_HEAD metadata so ordinary fetches do
not block safe expiration.

## Linked Issues or Issue Description

Refs #16457, #16586, #16621. Related performance work: #16579.

**What happened?**

After a finished workspace expires, its nested project checkout can
reopen at the current upstream commit instead of its previous commit.
Cleanup also treats local Claude settings as disposable, although that
file can contain user settings. Ordinary linked-worktree FETCH_HEAD
metadata prevents otherwise safe cleanup.

**Expected behavior**

Restore the main and nested repositories at their saved commits.
Preserve local settings bytes and permissions. Skip files and Git state
that cannot be reproduced. Permit standard fetched metadata only when
its commits remain recoverable.

**Steps to reproduce**

1. Prepare a managed nested project repository at commit A and add
ignored local settings.
2. Advance upstream to B, finish the task tree, and expire its workspace
and base.
3. Reopen the workspace through the normal service path. Before this
fix, nested preparation selects B.

## What Changed

- Extend the existing restoration recipe with exact nested commits,
branches, source identity, and encrypted local settings. Keep the schema
compatible with older recipes.
- Restore nested repositories and settings before provisioning. Recheck
company/project source access and preserve conflicting files on retry.
- Recheck recorded contents under cleanup locks before deletion. Persist
lock ownership before atomic publication so process exits recover safely
and foreign locks stay intact. Preserve changed or unsupported contents,
including tracked settings.
- Keep saved project repository selections through normal preparation.
Checkpoint restored contents before provisioning so failed setup can
retry without overwriting later edits.
- Accept bounded linked-worktree FETCH_HEAD records only after local
ancestry or fresh upstream proof. Preserve local-only fetched commits.
- Add real Git/Postgres lifecycle cases and focused content, access,
publication-retry, and fetched-state controls. Document the behavior.

## Verification

- `pnpm -r typecheck` passed.
- `pnpm build` passed.
- The original real Git/Postgres experiment failed with nested B instead
of A. The same path passes with this change.
- The integrated lifecycle suite passed 42 cases in 91.66s. Related
preparation, credential, content, and Git metadata controls passed 46
cases in 24.41s. The final heartbeat checkpoint persistence case passed
separately in 8.17s.
- Coverage includes exact main/nested commits, encrypted settings and
modes, upstream failure and retry, provisioning order, concurrent
reopening, changed unique files, tracked settings, malformed metadata,
and company boundaries.
- Exact-head CI passed the implementation, typecheck, build, security,
and test matrices. One browser shard passed on a single rerun after an
unrelated fixture teardown raced an activity-log write; its feature
assertions passed in the initial attempt.
- The broad local test run was stopped after about 12 minutes of
unrelated serial tests. Full parallel CI is required before merge; no
local full-suite pass is claimed.
- Single-workspace deployment, real-backlog reclamation, and ordinary
product reopening remain required acceptance work after merge.

## Risks

- Expired Git repositories still depend on upstream access. A failed
restoration returns the existing retryable error and never substitutes
the default branch.
- Saved settings use the existing local encryption provider. Recovery
requires that encryption key to remain available.
- Unsupported files, tracked settings, unknown sources, and unverified
Git state remain on disk. This can reduce reclaimed space.
- No database migration, recovery-retention change, public API, or
fleet-default change is included.

## Model Used

OpenAI Codex, GPT-6 family, with tool use, code execution, and an
independent agent review. The runtime does not expose a more specific
model identifier.

## 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-17 22:54:28 -05:00
DottaandPaperclip e6dcc6b095 Connect personal Muse through secure native execution and Vault OAuth (#16448)
Add company-scoped Muse native control, OAuth, wake receiver and recovery.

Recheck current authority after waits and before effects or receipt replay. Preserve task-read scope, assignment expiry, independent holds, nonblocking reassignment and truthful cleanup provenance.

Retain source trust on progress comments and verify current Muse V8 authority through real signed-JWT HTTP requests. Preserve the upstream trimmed ordinary authentication lookup.

Refs #16448.

Preserve captured canonical queue recovery and concurrent environment preparation while retaining the scoped Muse V8 exclusion. Normal migration 0354 and existing Muse SQL remain unchanged. Fresh current-head Greptile review is 5/5 with the project-write finding addressed. Required CI and independent technical review gate the merge; maintainer override is reserved for formal approval rules.

Recheck current Muse project-write authority after all receipt/task/run/admission waits, before creation or replay. Real PostgreSQL regressions reproduce four late effects/replays on the old route; the repaired three-file treatment passes 354 cases with no skips, and the scoped server typecheck passes. Ordinary/Dot behavior is preserved.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
canary/v2026.1018.0-canary.4
2026-10-17 22:44:36 -05:00
Devin FoleyandPaperclip 63fbb714e6 fix(server): release idle tracking after aborted static UI files (#16685)
## Thinking Path

> - Paperclip runs work for AI agents.
> - Hosts must prove that accepted work has finished before idle sleep.
> - HTTP request tracking keeps unfinished writes active after a client
leaves.
> - Static file middleware has no returned completion promise.
> - An aborted UI download can leave its request active forever.
> - This PR completes only a matched file response and keeps other work
tracked.

## Linked Issues or Issue Description

Refs #15522. Found while qualifying #16679. A search found no duplicate
static-download idle fix.

**What happened?**

Closing a client during a static UI download leaves one tracked request
active. The response has closed, but the file middleware never calls the
wrapped response end method. The instance cannot report idle after that
request.

**Expected behavior**

A closed, matched static file response must not leave a permanent work
hold. Unfinished application writes must remain tracked. A missing file
must keep the normal fallback and error paths.

**Steps to reproduce**

1. Serve a large local file through the static UI middleware with idle
admission enabled.
2. Start the download over HTTP.
3. Disconnect the client after its first data chunk.
4. Observe that the tracked request remains active with the original
middleware.

**Paperclip version or commit**

Reproduced on the behavior in
`d30648dee89720358271c276b9fc28cf83f18be7`. This branch starts at
`cfa9dce295970a85b3d8ee14cab0eccf50bc72e2`.

## What Changed

- Mark the completion of a known read-only response without dropping
pending middleware promises.
- Wrap static UI file serving. A successful file match is required
before a closed response can complete its tracking. A late match
rechecks an already closed response. Missing files keep the normal
fallback.
- Use the wrapper for hashed assets, other static UI files, and public
development files. Preserve caller headers and cache options.
- Test both HTTP abort timings, nested routers, conservative
mounted-application holds, parent writes, mutating GET fallbacks, and
callback-only work.
- Update the idle contract and its verification map. Correct the
paused-message recipe from hosted qualification: an explicit Pause
cancels older queued work, so test new accepted input after the pause
and await the normal resume lifecycle.

## Verification

- The original two real stream-abort regressions fail with the original
Express static behavior.
- Three review regressions fail on
`e260f4694afab8447b0cb203f439cb3ccad254e8`: a client closing before file
lookup, an unfinished parent in a mounted application, and an unfinished
parent in a root without installed handler tracking. Fixed sources were
restored byte for byte after the comparison.
- Two focused suites: 16 passed. They cover nested routers, both abort
timings, hidden parent writes, late missing-file fallbacks, contents,
HEAD, conditional responses, and caller headers.
- Module and map checks pass. Map checks are structural only.
- `pnpm -r typecheck` and `pnpm build`: passed on
`f242ee739344484995d3addf81635512370778c8`.
- Full CI matrix: 54 successful checks and 2 intentional Storybook
skips.
- Apex: 5/5 on the exact current head, with zero unresolved threads.
- Full local maintained test groups are still running before final
handoff.
- The initial local broad run was stopped before changing source for the
P1 review findings. Two file-mode fixture failures in that run came from
the scratch runner's inherited `0077` mask; the same suite passes with
the normal child test mask `0022`, without source or host configuration
changes. The replacement run uses `0022` for test children and
command-scoped `init.defaultBranch=master` for existing Git fixture
assumptions.
- This PR has not been deployed to a hosted environment.

## Risks

Only a matched file served by the admitted application with installed
handler tracking can complete this way. Routers share that scope.
Mounted Express applications and roots without handler tracking keep the
existing conservative response hold; this change does not claim their
hidden writes are tracked. An unfinished tracked parent promise still
blocks sleep after a file client disconnects. Redirects, missing files,
application callbacks, and other GET requests retain their guards. No
authentication, company scope, provider cleanup, or scheduling gate is
removed. No schema or API response changes.

## Model Used

OpenAI GPT-6 through Codex, with reasoning, source editing, and shell
tools. The session does not expose a more specific serving model ID or
its 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-17 20:28:57 -07:00
DottaandPaperclip 1f27427ffd perf(server): batch retained workspace reader identities and policies (#16683)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Task startup checks who can read each physical workspace.
> - A shared root retains the identities of earlier runs.
> - The service reloads the same agents, tasks, projects and run
policies for each reader.
> - Database round trips grow with the retained run history and hold the
company provenance lock.
> - This pull request batches these reads within each guarded operation.
Each run keeps its own identity and policy.
> - The benefit is less task preparation time while current access
checks remain in place.

## Linked Issues or Issue Description

Refs #16424.

**What existing behavior does this improve?**

Workspace admission, repository publication and batched read
authorization.

**Current behavior**

A synthetic shared workspace with 64 retained readers makes 680 SQL
calls during a publication check. The same principals are loaded
repeatedly.

**Proposed behavior**

Load retained identities and saved policies in batches of at most 500
IDs. Load project settings once per guarded operation. Reload records
and permission grants on the next operation.

**Reason and benefit**

The local service benchmark with an injected 4 ms loopback round trip
changed from about 7.0 seconds to 0.5 seconds and from 680 SQL calls to
47. This measures synthetic PostgreSQL data, not hosted response
latency.

## What Changed

- Extract retained-reader identity loading and acquisition trust checks
into a focused service module. Select only the identity and trust fields
used by these checks.
- Batch company-scoped run, agent and task lookups. Keep each run's task
binding, responsible user and policy checks.
- Batch saved run-policy reads in read authorization. Keep company and
agent identity checks and ordinary lookup behavior for noncanonical IDs.
- Reuse project settings within one root authorization operation.
- Add query budgets, identity failures, batch-boundary coverage, policy
comparisons and grant-revocation tests.
- Document snapshot lifetime and query scope.

## Verification

- PASS: 197 focused workspace and authorization tests.
- PASS: `pnpm -r typecheck`.
- PASS: `pnpm build`.
- PASS: all current-head hosted CI test groups, Runner checks, E2E
shards, security checks and builds (55 successful checks; two unrelated
Storybook jobs skipped). The local monolithic `pnpm test:run` was
stopped after all equivalent hosted CI groups passed. It has no complete
local result; the hosted matrix supplies the full-suite proof.
- Synthetic real-PostgreSQL benchmark: 383 workspaces and 64 retained
readers; 4 ms simulated loopback round trip. Publication check: 680 ->
47 SQL calls; 7.0-7.1 s -> 0.48-0.51 s. Three concurrent checks:
20.0-23.1 s -> 1.52-2.12 s. Setup and provider execution are excluded.
Live reply timing remains unverified.
- Regression coverage compares complete batched and ordinary
authorization decisions. It checks distinct saved policies for the same
principals, missing identities, company mismatch, task mismatch,
responsible-user mismatch, revoked project grants and changes after the
first operation.
- No new schema, API or UI contract.

## Risks

- A batch must not combine different runs' identities or policies. Each
lookup and policy decision retains its run, company and agent checks.
- Snapshots last for one guarded operation. Later admissions and
publications reload data. No authorization cache survives the operation.
- Restricted project trust checks keep their existing per-run validation
path. Hosted latency remains an acceptance gate.

## Model Used

OpenAI `gpt-6.1-sol` through Codex, with xhigh reasoning, code execution
and tool use. The runtime does not expose the configured 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>
canary/v2026.1018.0-canary.3
2026-10-17 21:52:08 -05:00
Dotta cfa9dce295 refactor(runner): remove unreferenced Paperclip Runner test fixtures (#16543)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - The Paperclip Runner package keeps fake agent servers and versioned
profile identity declarations under `test/fixtures/` for its test
suites.
> - Five of those fixture files have no reference anywhere in the
repository: no test, script, generator, workflow step, or document loads
or spawns them.
> - Dead fixtures add maintenance cost and make the referenced sibling
fixtures harder to trust.
> - This pull request deletes only those five unreferenced fixture files
and adds an audit receipt with the reference evidence.
> - The benefit is a smaller test-fixture surface with zero loss of
executed coverage.

## Linked Issues or Issue Description

**What existing behavior does this improve?**

The test-suite hygiene of the Paperclip Runner package. The repository
keeps unused test-support files that no suite loads. This slows audits
and makes the referenced fixtures harder to trust.

**Subsystem affected**

`packages/paperclip-runner` test fixtures.

**Current behavior**

Five files under `packages/paperclip-runner/test/fixtures/` have zero
references anywhere in the repository:

- `fake-native-resume-codex-app-server.mjs` (277 LOC): an old fake codex
app-server for resume testing. Resume coverage now runs through
`fake-final-burst-codex-app-server.mjs` (used by
`server/src/services/native-runtime/native-session-resume.test.ts:287`)
and `fake-durable-codex-app-server.mjs` (used by
`packages/paperclip-runner/src/live/live-session.test.ts:2192`).
- `copilot-profile-v{3,4,5,6}-identity.json` (64 LOC total): orphaned
profile identity declarations. Copilot profile tests,
`native-backend-factory.test.ts`, and
`scripts/generate-acpx-profiles.mjs` reference only v7 through v19 by
literal path. No dynamic `copilot-profile-v${...}` path exists in the
repository (the only template-literal fixture path is
`test-fixtures/pi-acp/profile-v${version}-identity.json`).

**Proposed behavior**

Delete only the five unreferenced fixture files. Keep every referenced
fixture. Keep all registered test cases unchanged.

**Reason and benefit**

Smaller test-fixture surface: 341 test/support lines removed with zero
loss of executed coverage. The audit receipt
`doc/plans/2026-10-16-runner-dead-fixture-test-audit.md` records the
per-file reference evidence.

**Breaking changes**

None. No production code, no registered test case, and no test selection
path changes.

**Additional context**

A repository-wide `git grep` for each removed filename stem returns zero
external references across all tracked file types. The
`hashFiles('packages/paperclip-runner/test/fixtures/**')` occurrences in
the workflows are Rust cache-key inputs, not execution selectors;
deleting files only changes that cache hash.

## What Changed

- Deleted
`packages/paperclip-runner/test/fixtures/fake-native-resume-codex-app-server.mjs`.
- Deleted
`packages/paperclip-runner/test/fixtures/copilot-profile-v{3,4,5,6}-identity.json`.
- Added the audit receipt
`doc/plans/2026-10-16-runner-dead-fixture-test-audit.md` with per-file
reference evidence.
- 341 test/support lines removed. Zero production, documentation, or
registered test-case changes.

## Verification

- Repo-wide `git grep -i` for each removed filename stem
(`fake-native-resume`, `native-resume-codex`, `copilot-profile-v3` …
`copilot-profile-v6`) across all tracked file types returns zero
external references.
- Selection audit: `packages/paperclip-runner/vitest.config.ts` includes
only `src/**`, `devtools/**`, `examples/**`, and two named
`scripts/*.test.mjs`; the server project selects `server/src/**` and
`server/scripts/**`; the `test:typescript:prep` `node --test` list names
no fixture. No workflow executes anything under `test/fixtures/` — the
`pr-trusted.yml`/`release-verify.yml`
`hashFiles('packages/paperclip-runner/test/fixtures/**')` occurrences
are Rust cache-key inputs, not execution selectors.
- Rust tests use their own `fake-codex-app-server` binary in
`runner/crates/runner-core`, not these `.mjs` fixtures.
- Searched open and merged PRs for each filename: zero overlap (`gh
search prs`).
- Repo-wide `pnpm -r typecheck`, `pnpm test:run`, and `pnpm build` were
not run this session: the removed files are unreferenced, absent from
every vitest/node-test include pattern, and excluded from all tsconfigs,
so no compiled or executed path changes. No runtime CI savings are
claimed.
- All Paperclip CI gates green on head `ce24ab3` (verified 2026-10-16
~09:00Z): every `ci /` shard (General tests, e2e shards, serialized
server suites, Verify Paperclip Runner rust/vitest/static, Build,
Typecheck + Release Registry, policy, Docker context integrity, Canary
Dry Run, gate), `review`, `Superagent Security Scan`, `Socket Security`
PR alerts + project report, and `Contributor trust` all pass; the only
skipped jobs are the Storybook deploy/visual-regression jobs, which are
not required for this change. Greptile Review: 5/5 confidence, "Low
impact", no actionable issues, last reviewed commit `ce24ab3`.

## Risks

Low risk. No executed coverage or selection path changes. The only side
effect is a one-time change to the `hashFiles` Rust cache key that lists
`test/fixtures/**`, which simply invalidates that cache on the next CI
run.

## Model Used

Zhipu `z-ai/glm-5.3` (GLM), served through OpenRouter, running as the
Paperclip Test Gardener agent. Context window size unavailable to the
agent. Capabilities used: shell tooling, git, GitHub CLI search, and
file inspection; no image or code execution capabilities were used.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` /
`Closes: #` / `Refs: #` OR (b) described the issue in-PR following the
relevant issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [ ] 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
canary/v2026.1018.0-canary.2
2026-10-17 21:18:11 -05:00
Devin FoleyandPaperclip e30550ef39 refactor: remove code comments added by recent PRs (#16681)
CONTRIBUTING.md says PRs add no code comments, but #16485, #16586, #16621 and #16672 added some. This removes the 215 comment-only lines git blame on master attributes to those merge commits, across 12 code files, plus one blank line the removal left doubled. Rewritten (not added) comments in scripts/assert-cloud-image-sentry.mjs and comments in .github workflows are left alone. No code changes.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-17 18:55:39 -07:00
Devin FoleyandPaperclip bebeb389f1 perf(server): do not watch bundled plugins for file changes (#16677)
Bundled sandbox-provider plugins are installed from local paths inside the image, so production started a chokidar dev watcher for each of them over files that never change. createPluginDevWatcher now takes unwatchedRoots (compared in resolved and real-path form), and the app passes the bundled plugin catalog root; plugins installed elsewhere are watched as before, and a plugin moving into an unwatched root closes its old watcher and cancels any pending restart.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-17 18:39:11 -07:00
Devin FoleyandPaperclip d30648dee8 Preserve accepted messages for paused recipients (#16679)
Keep accepted deferred requests pending while their recipient is paused and deliver through normal gates after resume. Preserve company, task hold, and cleanup checks.

Verification: 247 focused checks, recursive typecheck, the full CI test and build matrix, and Apex 5/5. The local Git fixture initial-branch limitation is documented in the PR.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
canary/v2026.1018.0-canary.1
2026-10-17 18:38:17 -07:00