Commit Graph
6613 Commits
Author SHA1 Message Date
DottaandPaperclip dce0042593 fix(server): wake chat receiver discovery from configuration and lease deadlines (#17572)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Chat receivers own persistent provider connections and fenced
database leases.
> - The chat maintenance timer repeatedly queries all eligible
receivers, including when none exist.
> - Configuration changes and known lease deadlines already identify
when discovery is needed.
> - This pull request moves receiver discovery to the shared delivery
coordinator.
> - Empty or settled discovery stops querying, while ownership and
recovery remain explicit.

## Linked Issues or Issue Description

Refs #17557. This is the next stacked slice after Discord command
registration. The base is `codex/sleep-19-discord-command-registration`.

**What happened?**
The recurring chat maintenance lane scans receiver inventory and
reconciles Discord and Photon runtimes even when configuration has not
changed.

**Expected behavior**
Reconstruct receiver work at startup. React to committed configuration
changes and local listener retirement. Retry foreign ownership at the
saved lease expiry. Stop discovery when there is no remaining
obligation.

**Steps to reproduce**
Start an instance with no chat endpoints. Let startup finish. Observe
the recurring receiver inventory query from chat maintenance. With a
configured receiver, remove its ownership token while listener shutdown
is delayed and signal a configuration refresh: the old implementation
can replace the listener before shutdown completes.

## What Changed

- Preserve healthy receiver progress after a slow failed batch while
retaining per-receiver retry backoff.

- Register a receiver discovery worker with scoped refreshes, paged
startup inventory, fair batches, and per-receiver or scope failure
backoff.
- Keep owned receiver identities cached without a discovery deadline, so
deletion still stops their listeners.
- Use existing transaction signals for configuration, credentials,
health, access revocation, company deletion, and provider lifecycle
changes. Rename the generic command-only helper to describe its broader
configuration contract.
- Keep lease-key selection with the receiver owner. Shared scheduling
contains no provider protocol.
- Retain stopping ownership until listener shutdown and lease release
complete. Concurrent acquisition joins the existing stop promise.
- Remove receiver discovery from the periodic chat lane. Preserve voice
and the other unmigrated duties.
- Record producer coverage, failure evidence, limits, and remaining work
in `doc/plans/2026-10-25-chat-receiver-discovery-sleep-audit.md`.

## Verification

Published head: `ab39569250f4b699a0ab7a829e66dbe27c15020b`. Discord
#17557 has landed at master `5bf0142d45`. A normal merge reconciles its
squash ancestry by applying only the recorded 27-file receiver patch
from parent `547fdf2139`. Every other path matches that master. Every
server and package production/test file is byte-identical to the
published `6e88ca0201` source that passed the 131-case run, typecheck
and build. Unrelated upstream UI/eval/documentation changes are
preserved. This PR targets master. Fresh exact-head reviews and CI are
required.

- **131 distinct targeted cases pass.** Five complete receiver,
coordinator, batching, startup, and GitHub health error-projection
suites pass 99 cases. Twelve real Discord
automatic-registration/receiver and Slack held-transaction cases pass
separately, with 1,581 other chat integration cases deselected. The
complete Photon channel suite passes 20 cases.
- The standalone receiver and Photon fixtures each reproduced
missing-table failures on separate initially empty PostgreSQL 17
databases. Both now apply pending migrations before client use; their
complete 20-case files pass on those same databases. The large chat
producer suite uses a separate migrated clone.
- The old review concerns already have source fixes: discovery stops
suppress their own completion wake at `1604a9fcba`; slow failed batches
supply `nextRunAtOnError` at `ab56393acc`. Guarded mutations prove the
existing regressions: reenabling the stop wake yields two inventory
reads instead of one, and removing the error deadline fails the 1,100 ms
provider-delay next-wake assertion. Both original source files are
restored byte for byte. Normal full worker and real producer suites pass
with those fixes.
- All 131 distinct targeted cases, production server typecheck and build
pass on source `6e88ca0201`. Exact source comparison carries that
evidence to this normal merge; the unchanged suites were not rerun just
for unrelated upstream changes. Receiver and Photon fixtures
self-migrate separate initially empty databases; the large producer
fixture uses its own migrated clone. Source is unchanged after these
checks. Recorded listener-count warnings and controlled provider failure
logs remain; no assertion was weakened. An initial whole-file identity
check rejected expected parent queue additions; precise patch comparison
confirms those declarations are correctly preserved.
- Old server shard 12 failed because GitHub reports that its self-hosted
runner lost communication. The grouped-test step is cancelled, and the
retained log has no failing assertion or completed summary. The
underlying host/resource/network cause is unproven. That interrupted job
is not a pass; the updated parent and fixture source require a fresh
full CI run.
- [Current acceptance and failure
record](https://github.com/paperclipai/paperclip/blob/ab39569250f4b699a0ab7a829e66dbe27c15020b/doc/plans/2026-10-25-chat-receiver-discovery-sleep-audit.md#compatibility-after-discord-squash-merge-october-27).
Prior 218-case and full-workspace results describe earlier revisions. No
full local repository-suite, multi-writer deployment, Cloud wake, host
suspension, or fleet cost claim is made.

## Risks

- Process-local transaction hints cover the active database owner and
its shared clients. Arbitrary direct SQL or independent configuration
writers need explicit wake integration. Startup/resume reconstruction
and known foreign-lease takeover remain supported; this does not add
general multi-writer discovery.
- Active receiver sockets and lease renewals continue. This change does
not prove host suspension or extend Cloud alarm coverage.
- Configuration signals can arrive during drain, initialization, or
shutdown. The worker preserves dirty scopes and the owner joins listener
retirement before replacement.
- Voice, Teams, milestone projection, publication maintenance, GitHub
recovery, and the remaining stack inventory are separate work.
- The Discord parent has landed and the receiver child now targets
master. Fresh exact-head reviews and all CI must pass before merge.

## Model Used

OpenAI GPT-6 via Codex, with repository inspection, code execution, and
test tools. The runtime does not expose a more specific deployment
identifier or 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 linked existing issues or described the issue in-PR
following the relevant issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links
- [x] My branch name describes the change and contains no internal
ticket identifier
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [ ] All Paperclip CI gates are green
- [ ] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-10-28 07:25:20 -05:00
DottaandPaperclip 1c7cbdc25b test(evals): preserve artifact outcome without extra task status gate
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-28 07:20:35 -05:00
DottaandPaperclip 3dab66775d fix(evals): bind answer race completion and ordinary draft evidence
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-28 07:20:35 -05:00
DottaandPaperclip 7d8bab773d perf: avoid full JIT and activity scans in Mine unread badges (#17973)
## Thinking Path

> - Paperclip helps people manage AI agents and their work.
> - Mine includes tasks the person created, was assigned, or
participated in.
> - Its unread badge ranks the visible personal top 100 before checking
unread state.
> - Correlated participation and privacy predicates can trigger
expensive PostgreSQL JIT work.
> - This change joins native participant IDs before ranking a narrow
candidate projection.
> - A partial actor index avoids scanning company activity history for
each badge.
> - Local representative scoped reads improve while dense unrestricted
overhead remains explicit.

## Linked Issues or Issue Description

**What existing behavior does this improve?** The Mine unread badge in
the company sidebar.

**Current behavior:** A fresh five-minute window recorded 402 ranking
calls and 31.7 seconds of SQL time. Correlated predicates can spend more
time compiling than executing.

**Proposed behavior:** Build the same company-scoped participant set,
use native issue keys, apply fresh authority before the top-100 limit,
then retain the original canonical rank and second unread query.

**Reason and benefit:** Reduce full JIT compilation and avoid an
unindexed company-history activity scan. Realistic activity-only
participation is included in the measurement.

**Breaking changes:** No API or policy change. This PR adds one
concurrent partial index migration. Related Mine rules in #16356 and
#17756 are preserved.

## What Changed

- Join distinct native participant IDs; guard exact legacy text before
UUID conversion.
- Skip redundant activity participation already covered by
creation/assignment. Sort a narrow eligible candidate projection before
canonical activity ranking.
- Share existing pending-request and user-activity predicates with
ordinary Mine reads.
- Add partial `activity_log(company_id, actor_id, entity_id)` for
user-authored issue activity. Register its idempotent concurrent
migration with the existing top-level/invalid-index-repair runner.
- Add real PostgreSQL coverage for visible top 100,
unread/archive/source semantics, exact IDs, company scope and fresh
grant/private-project access.
- Add a pinned service benchmark with separate pre-index/indexed
databases, identical data, full positional equality, ordinary-call
timings, plans and real migration/cancellation proof.

## Verification

- Fourteen focused PostgreSQL 17 tests pass (16.37 s), including
assembled badge routes and grant revocation. Full workspace typecheck
and build pass on the final production sources.
- The earlier full local suite is incomplete: native PostgreSQL startup
exhausted system semaphores, independently reproduced with empty initdb.
All sixteen failed cases passed with task-owned Docker PostgreSQL 17.
This is not counted as a full local-suite pass. Full Linux CI passes on
final head `f44e46ce580e8345209d7165f57bd8bf696c517c`. Greptile and
Paperclip Review are both 5/5 with zero unresolved comments.
- Baseline `70c864633744cd96c0dc7394d631fc7119cd17d2`; source and DDL
hashes retained. Two warmups and five alternating samples per arm/cell.
Capture and EXPLAIN occur outside timed ordinary service calls.
- All twelve 300k-history cells match complete positional rows in both
SQL phases and final returned IDs. Half the personal tasks qualify
through activity alone; the actor index contains matching and
other-human rows.

| Local service case | Before median | After median | Before / after |
| --- | ---: | ---: | ---: |
| dense / unrestricted / JIT on | 18.33 ms | 25.06 ms | 0.73x |
| dense / scoped / JIT on | 909.30 ms | 221.10 ms | 4.11x |
| sparse / unrestricted / JIT on | 13.64 ms | 5.84 ms | 2.34x |
| sparse / scoped / JIT on | 719.07 ms | 10.79 ms | 66.64x |

Small paths add at most 0.6 ms at the median. Dense unrestricted paths
regress by 6.7–7.7 ms; dense scoped JIT-off is approximately neutral
(218.34→223.24 ms). Sparse JIT-off paths improve too. This is not a
uniform speedup.

The actual baseline fails the compiler-work assertion. The final query
avoids full JIT optimization/inlining and exceeds 1.5x where the old
plan triggers those passes. Small/sparse controls meet the 25% or 2 ms
allowance. Dense no-JIT cases are explicit diagnostics. The optional 60
ms absolute goal still fails at 221.10 ms on dense scoped reads:
substantial privacy-predicate execution remains after compilation is
removed. The failure is retained rather than counted as green.

The actual normal migration runner upgraded 300k activity rows in 668.79
ms including inspection, index build/validation and journal work. Rerun
took 21.83 ms; a deliberately cancelled build left an invalid index, and
retry repaired it in 187.71 ms. Concurrent reads/writes completed; the
final index was 188416 bytes. No migration was run on the hosted
database.

The million-row mixed-participation sparse control also passes all four
visibility/JIT pairs with complete equality: unrestricted JIT-on
13.44→5.76 ms; scoped JIT-on 807.76→11.59 ms. The actor branch visits 36
indexed rows rather than scanning company history. Actual
migration+runner took 255.06 ms; rerun 20.32 ms; cancellation
repair/retry 241.73 ms. Concurrent reads and writes completed without
failures.

Reproduce:

```sh
pnpm --filter @paperclipai/server exec tsx ../scripts/benchmark-mine-unread-badge.ts --baseline-ref=70c864633744cd96c0dc7394d631fc7119cd17d2 --history-decoys=240000 --verify-migration --assert-performance --evidence-dir=<directory>
```

Add `--fixture=sparse --history-decoys=940000` for the million-row
control. The default harness starts disposable embedded PostgreSQL and
ignores DATABASE_URL. Recorded evidence used PostgreSQL 17.11 through a
scratch constructor provider because the host native runtime has
semaphore limits. All normal database allocation/migration/client paths
are retained.

Source-only EXISTS/lateral alternatives were measured and rejected after
company scans or sparse regressions. A time bound would lose historical
participation, and existing indexes cannot select a user's activity.
This justifies the exceptional partial index migration. The exact sample
ranges, plans, failures, source hashes, migration footprint and
feedback-loop timing are in
`doc/plans/2026-10-27-mine-unread-badge-query.md`.

## Risks

- Dense unrestricted reads are slightly slower, and dense scoped reads
retain substantial authority work. The PR removes a compilation/lookup
bottleneck rather than all badge latency.
- The concurrent build scans activity history and can wait for
long-lived transactions. Local build/cancellation timings do not
guarantee the duration on larger or slower hosted databases.
User-authored issue activity gains one narrow index to maintain.
- Participation, visibility, ranking and legacy ID semantics must remain
exact; the real database regressions exercise those boundaries.
- Hosted improvement is unverified. The affected ranking SQL averaged
78.8 ms while HTTP badge requests averaged 752 ms without correlated
traces. No merge or deployment is included.

## Model Used

OpenAI Codex, GPT-6 family, with reasoning, tool use and local code
execution. The runtime does not expose the exact model ID or context
window to this 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
- [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-28 07:20:08 -05:00
Dotta af01c4f6d3 fix(evals): await fast response save before model readback 2026-10-28 07:19:59 -05:00
DottaandPaperclip a91f78e7e0 perf(chat): reduce inbound queue discovery cost (#17971)
## Thinking Path

> - Paperclip helps people manage companies of AI agents.
> - External chat messages enter a durable delivery queue.
> - Queue reads must preserve pending wake ownership and conversation
order.
> - Retained processed history increases the estimated cost of a
correlated pending-action test.
> - PostgreSQL 17 enables JIT for these small selectors and reads extra
JSON in deadline discovery.
> - This pull request uses a scoped pending-action set for open-work
discovery.
> - The benefit is less database work with the same selected deliveries
and deadlines.

## Linked Issues or Issue Description

**What existing behavior does this improve?**

Inbound delivery deadline discovery and conversation-head selection.

**Subsystem affected**

Server chat queue discovery.

**Current behavior**

A correlated `EXISTS` inside an `OR` has a high cost estimate on
retained completed history. PostgreSQL 17 already hashes its
pending-action read, but the estimate still enables JIT. Deadline
discovery also reads JSON from completed deliveries that have no pending
wake.

**Proposed behavior**

Use `(company_id, endpoint_id, delivery_id)` membership in the
pending-action set for the two open-work selectors. Keep ready-only
evaluation on its original scoped `EXISTS`. Keep retry, lease, ordering,
lifecycle and endpoint rules.

**Reason and benefit**

The local retained-history fixture reduces deadline selection time. The
small control and the final head selection are neutral. Ready-only
selection remains an unchanged control.

**Breaking changes**

None. No API, schema, migration, stored history, worker, timer or
notification changes.

Related work: #17647 and #15927 change inbound wake-notice scheduling
and selection. This PR changes the separate conversation queue ownership
predicate.

## What Changed

- Use a fully scoped pending-action set for open-work discovery. Exclude
null delivery IDs to preserve exact boolean results. Keep duplicate
actions from multiplying deliveries.
- Preserve the original ready-only query.
- Add five real PostgreSQL tests and a reproducible baseline/treatment
benchmark. Capture the complete real service SQL, parameters, positional
rows and execution plans.
- Document the query cause, rejected hypotheses, test results and limits
in `doc/plans/2026-10-27-inbound-queue-query-proof.md`.

## Verification

Pinned pre-fix baseline: `09ad9adce2cf4742944353a3707a2f908e9bb35e`.

Local fixture: Linux ARM64 PostgreSQL 17.11, Node 26.4.0. It has 1500
completed deliveries and actions, two open deliveries, and 32 KiB of
synthetic incompressible JSON per historical delivery. A separate
control has 20 completed rows. The normal settings use JIT on with a
100000 cost threshold, 128 MiB shared buffers and 4 MiB work_mem.

The final quiet retained-history pair measured these local SQL medians.
Each
arm has two warmups and five alternating samples. The small control is
neutral.

| Actual selector | Baseline | Treatment | Complete positional output |
| --- | ---: | ---: | --- |
| Next inbound deadline | 18.78 ms | 1.58 ms | Equal |
| Conversation head | 5.71 ms | 6.18 ms | Equal |
| Ordinary ready control | 9.23 ms | 8.33 ms | Equal ; unchanged |

The deadline plan uses fewer shared buffers. Head physical reads remain
unchanged. Deadline discovery avoids JIT on this fixture. The pristine
head estimate is below the JIT threshold in both arms, and its timing is
neutral. With JIT disabled, deadline discovery still improves; head and
ready timings overlap.

- Red: the unchanged baseline fails the explicit local fixture work
budget for JIT and deadline buffer reads. Green: the treatment passes.
There is no timing threshold in ordinary CI.
- Five new PostgreSQL tests and six existing assembled chat tests pass.
They cover scoped/null/duplicate pending actions, boolean results,
payloads, head barriers, reactions, paused/attention/AgentMail
exclusions, retry/processing deadlines, provider ordering, lease loss,
lifecycle retry and edit/admission races.
- Actual old/new ready selectors have equal error outcomes for unrelated
malformed retry timestamps. An initial AND-only oracle comparison was
inconclusive and is not defect evidence.
- `pnpm -r typecheck` passes.
- `pnpm build` passes.
- Final head `f3cac298d8a8a5377127b0db7057c52019bbe426` passes the
complete [CI
workflow](https://github.com/paperclipai/paperclip/actions/runs/40625611887).
Greptile is 5/5 on that head with no unresolved review threads. The
earlier end-to-end cleanup lock-timeout failure passed on this revision.
- The complete local suite was not run. The host's known native
PostgreSQL startup failure exhausts SysV semaphores. Focused integration
tests use a disposable Docker PostgreSQL constructor through the
existing test seam. Complete final-head CI is required.

Reproduce the real SQL comparison:

```sh
pnpm --filter @paperclipai/server exec tsx ../scripts/benchmark-inbound-queue-discovery.ts --baseline-ref=09ad9adce2cf4742944353a3707a2f908e9bb35e --require-work-budget --retained-only
```

Use `--jit-off` for the diagnostic control. The default command uses the
repository's bundled PostgreSQL version and records it in output. The
reported 17.11 run used the existing test constructor seam with a
disposable `postgres:17` container. Raw samples, complete queries,
parameters and plans are emitted as JSON. The benchmark uses disposable
synthetic data and does not read a live database URL.

## Risks

- Query plans depend on data and PostgreSQL settings. These local
measurements do not prove deployed speed or request latency.
- Head selection still reads historical JSON. Action history remains
stored and scanned. This is not a constant-time queue implementation.
- The changed false branch has no retry timestamp cast. Ready-only
parsing, claims and retries stay on their existing query.
- Background SQL totals can overlap. Do not add these savings into an
HTTP latency claim. The largest possible saving for an affected
selection is bounded by its observed SQL time, about 49–53 ms on average
in discovery.

## Model Used

OpenAI Codex, GPT-6 family, with tool use and code execution. The
runtime does not expose the exact model ID or context-window size. Three
parallel agents own separate performance fixes; this PR contains only
the inbound queue fix.

## 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-28 07:19:22 -05:00
DottaandPaperclip f69dfc0e23 perf: use indexed latest-run probes for task interruption lists (#17969)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Task lists show the latest run's interruption state for each visible
task.
> - The old lookup applies a coalesced text expression to company run
history.
> - That lookup cannot use the separate binding indexes for a small task
page.
> - This pull request selects the newest run through those existing
indexes.
> - The benefit is less database work with the same interruption result.

## Linked Issues or Issue Description

**What existing behavior does this improve?**

The latest-run lookup used by task-list interruption enrichment.

**Current behavior**

The query scans company history for a coalesced native, first-class, or
legacy task ID. A local two-task fixture inspects 1,506 runs to select
six candidates. A recent hosted sample recorded about 110 ms per
latest-run lookup. This is one part of the list handler, not its whole
latency.

**Proposed behavior**

Probe each existing binding index for the newest candidate. Pick the
newest candidate across the three binding branches. Read the same
evidence fields in the same SQL statement. Preserve native precedence,
first-class precedence, legacy text matching, company scope, and
ordering ties.

**Reason and benefit**

The representative local 100-task page improves from 17.17 ms to 3.00 ms
(5.72×). A modern 100-task page with 40 runs per task improves from
26.78 ms to 3.82 ms (7.02×). All positional SQL fields, row order, and
full service results match.

**Breaking changes**

None. Stored history, API fields, visibility filtering, execution
authority, and external-conversation state are unchanged.

Related behavior: #16965, #17509, #17552. The duplicate search found no
open PR for this query rewrite. ROADMAP.md has no duplicate planned
feature.

## What Changed

- Use three disjoint indexed candidate branches with a lateral
newest-run selection.
- Guard UUID parameters to preserve the old text matching for
noncanonical input.
- Keep final evidence projection in the same database snapshot.
- Add real PostgreSQL work and contract regressions, a pinned-source
benchmark, and a verification note.
- Require the plan regression to find real run-table nodes. Record the
deep-native-history follow-up without adding indexes or DDL.

## Verification

- Baseline red: the real two-task lookup inspects 1,506 run rows and
fails the work bound. The unchanged semantic oracle passes.
- Treatment green: both PostgreSQL query regressions pass. They cover
conflicting bindings, malformed JSON, empty values, noncanonical IDs,
duplicates, foreign companies, missing runs, and timestamp ties across
branches.
- Seven paired PostgreSQL 17.11 cases pass complete positional SQL and
full service equality. Each arm has two warmups and five alternating
measured samples. Fixture payload sizes are random input bytes before
Base64 encoding: 24 KiB becomes 32 KiB of stored text per noise field.
- Representative 100 × 12 history: 17.17 ms (16.79–17.48) → 3.00 ms
(2.64–4.28). Shared buffer hits: 30,033 → 3,400.
- Modern 100 × 40 history: 26.78 ms (25.79–27.40) → 3.82 ms (3.47–4.78).
- The benchmark command, all cases, plans, fixture limits, and
feedback-loop timing are described in [the verification
note](doc/plans/2026-10-27-task-interruption-query-performance.md).
- Reproduce with `pnpm --filter @paperclipai/server exec tsx
../scripts/benchmark-task-interruption.ts
--baseline-ref=09ad9adce2cf4742944353a3707a2f908e9bb35e`.
- `pnpm -r typecheck` and `pnpm build` passed at
`20d46e3a16d10cf3c5399fc1211b17db6a4afdc6`. The current head has the
identical production runtime; it adds one test assertion and
documentation.
- The focused query, real project-access repair/retry, and presentation
suites pass: 19 tests across three files. The earlier plugin-sdk loading
failure is resolved by normal build setup.
- `pnpm test:run` was attempted, then stopped after repeated native
embedded PostgreSQL bootstrap failures. The full local suite is
incomplete. All 16 affected real-DB executor cases pass when rerun with
disposable PostgreSQL 17 in Docker.
- Linux CI passes the full server suites on this head. One unchanged
Runner close fixture failed on the first CI attempt; its source tree is
identical to the passing upstream #17439 baseline. One targeted job
retry passed on the original head. Fresh checks run again for the
test/documentation review fix. A separate macOS diagnostic fails the
unchanged close variants too; that close issue is not diagnosed or
counted as a local pass here.
- The original head passed 55 checks with one neutral result and two
expected Storybook skips. Greptile gave 5/5. The current head adds one
nonempty-plan assertion and documents the deep-history follow-up. Its
focused PostgreSQL suite passes 2/2. Final head
`c1db106d7ab56b530af82d2bb0556feb0eda290b` is mergeable with all CI
checks complete and passing, Greptile 5/5, and no unresolved review
findings; the documented per-task history limitation remains an explicit
follow-up.

## Risks

- More index probes add about 0.43 ms to the one-run tiny control. The
maximum 1,000-task page with one modern run per task is 9.99 → 14.11 ms,
a 4.12 ms regression. Dense history pages save substantially more in the
local fixture.
- Each branch can still walk one task's own history. The first-class and
legacy probes can discard native-bound rows after index lookup. The plan
note specifies a 10,000-run follow-up, migration-free alternatives, and
a measured index-build budget if indexes prove necessary. This PR does
not make work independent of history depth.
- Local SQL results do not prove deployed HTTP gains. The affected query
averaged about 110 ms in the hosted sample; its critical-path
contribution can be smaller because other enrichment reads run
concurrently.
- The main issue-list SQL and external-conversation gates remain
separate work. This PR has no migration or startup job.

## Model Used

OpenAI Codex, GPT-6 family, with code execution and repository tool use.
The runtime does not expose the exact 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-28 07:18:17 -05:00
DottaandPaperclip 356c7de9b7 fix(runner): bind Grok packs to current admission source (#17972)
## Thinking Path

> - Paperclip manages agents and their work.
> - Native agents use verified Runner and provider-pack artifacts.
> - A protected installed pack can be reused when its selected provider
profile matches.
> - Grok kept profile 1 when its sidecar gained effort, search, and
startup diagnostics.
> - An older Grok sidecar can therefore pass compatibility and reject
the new session fields before provider startup.
> - This PR binds the current Grok profile to its admission source so a
fresh run selects the current verified pack.

## Linked Issues or Issue Description

Refs: #17922, #17942, #17962. Related installation contract: #14024. No
duplicate repair was found.

**What happened?**

The selected Grok profile digest stayed unchanged across native session
contract changes. The installed-pack verifier correctly compared that
digest, but the unchanged value let a pre-effort sidecar satisfy a
current controller. That old parser rejects `grokEffort` and
`grokDisableWebSearch` before the new startup diagnostics run.

**Expected behavior**

A fresh Grok run must use a pack that supports its current session
contract. Source-only app changes must still permit warm reuse when the
selected Grok profile matches. Reattachment must keep its exact admitted
artifact authority.

**Steps to reproduce**

1. Retain a protected pack with published Grok profile 1 and ACPX
interface 1.
2. Upgrade the controller to the native effort and search contract.
3. Start Grok 4.7 with High effort and disabled web search.
4. The old profile passes installed-pack compatibility, but its sidecar
rejects the new fields.

**Paperclip version or commit**

Reproduced from master at `09ad9adce2cf4742944353a3707a2f908e9bb35e`.

## What Changed

- Advance Grok to profile 7. Keep historical versions 1–6 decodable and
keep the Grok 1.0.13 runtime pin.
- Stamp the Grok admission source identity into a generated launcher
comment. Keep the existing physical command-byte digest check unchanged.
Bind effort/search/credential handling, sidecar admission, and Rust
backend/session/diagnostic source.
- Check the source attestation in the existing TypeScript/Rust profile
build gate. Keep its required fixture in the Docker context. Refuse to
overwrite a versioned identity after source changes.
- Add regression coverage for rejecting the old pack, current-profile
warm reuse, exact historical recovery authority, and actual sidecar
dispatch of Grok 4.7 High with both search policies.
- Re-attest Copilot as profile 71 because its bound shared recovery
decoder now retains Grok 6. Preserve Copilot 70 and all earlier
identities. Keep the compatibility algorithm, other provider identities,
dependencies, lockfile, and workflows unchanged.

## Verification

- The production installed-pack regression failed before the profile
update: the old Grok pack was accepted. It now passes.
- 105 server manifest, artifact, archive, and authority tests passed.
- 246 Runner profile, physical launcher integrity, Grok
effort/search/credential, and actual sidecar process tests passed; six
existing platform cases were skipped.
- 31 Node packaging and identity tests passed, including an actual
generator CLI regression that preserves all authority files when a
versioned identity would change.
- 55 Rust ACPX unit tests and 17 real sidecar pipe tests passed. After
the final profile declaration, all 55 unit checks passed again.
- Final `pnpm -r typecheck` and `pnpm build` passed at the final source.
- CI on the preceding head caught Copilot’s stale attestation for the
shared recovery decoder. The same current-source test failed locally,
then passed after profile 71 was generated with version 70 retained. All
106 affected Copilot/profile checks pass. Final head
`78e6d76fc52f492371e15574482b3641735a6d89` passed the full CI workflow;
the failed prior job log is retained.
- Review follow-up: mutating the Rust backend’s actual Grok descriptor
field left the prior identity unchanged. This regression failed before
binding `acpx_provider_backend.rs` and passes afterward. Profile 7
retains the prior versioned fixture and recovery decoder. All 179
affected Runner checks and 75 focused server pack/manifest checks passed
after this change.
- `pnpm test:run` hit the recorded embedded PostgreSQL bootstrap failure
after five attempts. The full run also exposed a current-release fixture
with the historical Grok digest; it now reads the current profile. Its
11 focused manifest tests now pass. The failed local run log is
retained; final exact-head CI passed.
- The same filtered-context Docker build that failed CI now passes
locally after adding its required source fixture.
- A separate probe used the built sidecar in a private HOME with no
credentials. It admitted the current profile and the new Grok fields,
then returned the closed working-directory rejection before provider
launch or inference.
- A historical parser probe reproduced the pre-effort sidecar rejection.
These probes establish the contract boundary; they do not establish
native subscription task acceptance.
- Initial restricted local ownership tests failed because loopback
listeners were denied. The same tests passed with loopback access. One
new dispatcher fixture first lacked required instructions; the completed
request passed. These setup failures are retained in local evidence.
- Live native task acceptance remains pending deployment. Earlier
deployed attempts failed before tool output. No successful native shell
proof is claimed.

- Final exact-head merge gate: all 62 contexts are clean (57 success,
four intentional skips, one informational neutral formal review).
Greptile and Paperclip reviews are both 5/5, with no unresolved
actionable threads. The formal review uses the existing report-only
neutral policy.

## Risks

- The first fresh Grok run after upgrade may need to stage the current
provider pack. Matching current profiles keep their existing reuse path.
- Fresh admission rejects older Grok profile identities. Historical
decoding and exact reattachment authority remain separate; this change
does not reinterpret an old identity or replace an active session's
pack.
- Future changes to bound source require a new Grok profile attestation.
The build gate fails if the checked-in identity is stale.
- Model, effort, search, credential, approval, and retry policy are
unchanged.

## Model Used

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

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass (focused checks; full-suite
database failure is retained 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>
canary/v2026.1028.0-canary.8
2026-10-28 07:15:13 -05:00
Dotta 9ea0c8a61d fix(evals): retain original clock for seven prepared human journeys 2026-10-28 02:31:43 -05:00
DottaandPaperclip cff331f6ca fix(evals): retain local controller cost origin (#17990)
## Thinking Path

> - Paperclip manages AI agents and their work.
> - Its eval journals retain model costs and operating reservations
under one cap.
> - The operating policy records the controller's execution origin.
> - The schema currently accepts only GitHub-hosted and AWS Fleet
origins.
> - A local controller must therefore use an inaccurate label or fail
admission.
> - This PR adds the local origin and keeps the hosted-only schedule
gate.

## Linked Issues or Issue Description

Refs #17986. No duplicate open PR or issue was found in the
operating-overhead/local search.

**What existing behavior does this improve?**

The Product E2E operating allowance and its retained journal policy.

**Current behavior**

At master `40c1ab36cd`, an unscheduled local controller cannot set
`runner: "local"`. The generic allowance validator rejects it. Local
qualification can use the same accounting controls but cannot record its
origin correctly.

**Proposed behavior**

Accept the local origin in the generic allowance. Keep all component,
price, cap, expiry, and receipt rules. The scheduled validator still
requires `github-hosted` and rejects a local allowance.

**Reason and benefit**

Local qualification can retain an accurate execution origin without
claiming that its reservations are billed GitHub charges.

## What Changed

- Add `local` to the operating allowance's runner type and validator.
- Exercise local journal creation, model admission, retained overhead,
restart, and reconciliation in the existing boundary test.
- Check that a local allowance fails Product scheduled admission.
- Pin new hosted Runner controller admission to `github-hosted`.
Preserve original labels when reading historical manifests; those reads
cannot authorize a new worker.
- Exercise the hosted-origin rejection and historical/local reads in
both source and copied portable runtimes.
- Document the local label and its accounting limits.

## Verification

- Before the fix: the new local persistence case and schedule-boundary
assertion failed; eight tests passed.
- Focused ledger, overhead, operations, and scheduled finalization
tests: 71 passed across five files.
- Controlled Runner source and portable tests: 86 passed. The new
hosted-origin regression failed before the fix.
- Full Product support suite at the first commit: 4,524 passed, three
skipped, and one retained embedded PostgreSQL bootstrap failure. The
same database failure was previously reproduced on a clean baseline.
- Separate Node test phase on the host: 137 passed.
- Actual Linux controller: database lifecycle tests pass. After
installing its missing `zip` utility, the full Product suite has 4,527
passes and one Copilot parent-version coverage failure. That same
failure reproduces on clean master `40c1ab36cd` with the same Linux
filesystem and dependencies (14 passes, one failure). Copilot files are
unchanged. The initial seven ZIP-related failures and the watcher
failure remain retained.
- The final fresh Linux semantic check passes: `GOMEMLIMIT=2GiB GOGC=50
GOMAXPROCS=1 node node_modules/typescript/bin/tsc --singleThreaded -p
tests/runner-e2e/tsconfig.json`. The parallel compiler OOM is retained.
No semantic checks were omitted.
- Both fresh reviews are 5/5, with the addressed thread resolved. Hosted
Build first failed during unchanged Pi setup prefetch with an operation
timeout. One job rerun recovered; the original failure remains retained.
All 58 latest-head checks are now acceptable.
- No paid model requests, sandbox creation, schedule changes, or
historical journal edits.

## Risks

- The caller supplies this origin. It must describe the actual
controller.
- `local` does not prove zero compute cost, provide a default allowance,
or release a hold.
- Both maintained hosted admission paths require the GitHub-hosted
controller origin. A previously accepted hosted policy with an AWS/local
label now fails new admission. Historical reads preserve the original
evidence.

## Model Used

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

## Checklist

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

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-10-28 02:05:36 -05:00
Dotta d282ae2eee fix(evals): share original observation clock across selected native phases 2026-10-28 02:01:44 -05:00
Dotta 81abf04b21 fix(evals): qualify owned OpenCode post-stop proxy cleanup 2026-10-28 01:32:20 -05:00
Dotta 15fb2318bf fix(evals): preserve human origin on consumed queue probes 2026-10-28 01:32:20 -05:00
Dotta b70439f387 fix(evals): keep deadline boundary timeout strictly positive 2026-10-28 01:32:20 -05:00
Dotta b0eff403b8 fix(evals): share original budget for instance and confirmation waits 2026-10-28 01:32:19 -05:00
Dotta e232200747 test(e2e): pin configurable auxiliary tests to requested model 2026-10-28 00:55:14 -05:00
DottaandPaperclip 40c1ab36cd feat(evals): register explicit Daytona feedback persistence (#17986)
## Thinking Path

> - Paperclip manages AI agents and their work.
> - Product E2E evals check real server, browser, runner, and provider
behavior.
> - Feedback persistence already checks saved complaints and suggestions
with exact bodies and run attribution.
> - Its catalog registers only local cells, so a Daytona campaign cannot
select the same workflow.
> - This PR registers the existing workflow for the two native Daytona
profiles and tests their gateway bindings.
> - Remote cells stay explicit-only and unqualified until a bounded live
run passes.

## Linked Issues or Issue Description

Refs #17980 and #17975. No duplicate open PR or issue was found in the
Daytona feedback search.

**What existing behavior does this improve?**

The `feedback-persistence` Product E2E suite and its explicit execution
selectors.

**Current behavior**

At master `d54f776ca0`, the suite has only local Claude and Codex cells.
Selecting the matching Daytona ID fails before admission. The gateway
manifest already supports these native remote profiles.

**Proposed behavior**

Register four cells: local and Daytona for each native profile. Reuse
the existing saved-body and completed-tool oracle. Require an immutable
image and Daytona credentials. Keep one attempt, one expected work run,
five-minute local and inherited 15-minute remote case timeouts, and the
existing 60-minute provider creation TTL.

**Reason and benefit**

A bounded remote qualification can check both a simple task and real
feedback persistence. Local evidence remains separate from remote
acceptance.

**Breaking changes**

Explicit `--suite feedback-persistence` now lists four cells instead of
two. `--all` still excludes the suite. Daily and weekly manifests still
select their existing exact local IDs.

## What Changed

- Register the two native Daytona feedback cells and increment the suite
definition version.
- Address the remote cold-start review: inherit the base task's
15-minute Daytona deadline and retain the five-minute local limit. The
regression failed before the fix and now passes.
- Check immutable-image requirements, credentials, lifetime, and shared
gateway connections in existing contract tests.
- Fix the config type in the TTL catalog test added by #17980. Keep its
runtime lifetime assertions.
- Document remote selection and its unqualified status in the existing
eval guides.

## Verification

- Before the catalog change, the registration regression failed: one
failed and 16 passed.
- Focused catalog, feedback, operations, ledger, manifest, and summary
tests: 114 passed across six files.
- Read-only discovery lists exactly the two Daytona feedback IDs.
- The Node test phase passes separately: 137 tests. The retained Vitest
database failure prevents the unit launcher from reaching that phase.
- Full Product support suite: 4,523 passed, three skipped, and one
embedded PostgreSQL bootstrap failure. The same database failure was
reproduced on a clean baseline before this PR.
- Fresh Linux Product typecheck passed at the review-fix commit:
`GOMEMLIMIT=2GiB GOGC=50 GOMAXPROCS=2 node
node_modules/typescript/bin/tsc -p tests/runner-e2e/tsconfig.json`. The
default run and the ineffective JavaScript-heap attempt exited 137 and
remain retained. The compiler launches a native child process; its
memory controls let the unchanged semantic check complete. Host
typecheck still has 15 stale installed DB/Runner export errors; the two
TTL test typing errors are fixed. All 58 latest-head checks are
acceptable (success, neutral, or skipped). Both fresh reviews are 5/5,
with no unresolved review threads.
- The updated credential-free Linux controller discovers both planned
remote IDs and launches Chromium 151.0.7922.34. Runtime build inputs are
unchanged from the prior controller. The Daytona image content ID is
still
`b55f03dc9c633db300b70206a691ff45a8e779e56a3c546f9358e3282d3597c9`.
- No model requests, sandbox allocation, or paid schedule changes.

## Risks

- Selecting the whole explicit suite now includes remote cells and
requires Daytona configuration. Use exact IDs for a bounded paid
campaign.
- Registration and contract tests do not prove live remote behavior or
token accounting. Remote qualification remains pending.
- The shared dependency checkout limits the local host typecheck. The
fresh Linux semantic check passed. Earlier compiler OOM failures and the
database bootstrap failure remain retained.

## Model Used

- OpenAI GPT-6 through Codex, with tool use and code execution. 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>
nightly/v2026.1028.0-nightly.0 canary/v2026.1028.0-canary.7
2026-10-28 00:54:04 -05:00
Dotta 1e686fa0f3 fix(evals): bind routine failure evidence to selected profile 2026-10-28 00:53:18 -05:00
Dotta 78783dda57 fix(evals): bind routine history grading to observed provider 2026-10-28 00:47:54 -05:00
Dotta 765dd51e0f test(e2e): retain context custody across budget handoff 2026-10-28 00:37:55 -05:00
Dotta fa7304ae5e test(e2e): share original budget across company followups 2026-10-28 00:37:55 -05:00
Dotta 6eca7f6bcc test(e2e): verify returned historical artifact copies 2026-10-28 00:25:04 -05:00
Dotta 2c6d746015 fix(evals): retain contracted delivery negation in date grading 2026-10-28 00:25:04 -05:00
Dotta fefc475470 fix(evals): accept exact natural historical delivery dates 2026-10-28 00:25:04 -05:00
Dotta 8b29ca5489 fix(evals): enable real workspace view before lifecycle journeys 2026-10-28 00:21:59 -05:00
DottaandPaperclip d54f776ca0 fix(daytona): bound ephemeral eval lifetime at creation (#17980)
## Thinking Path

> - Paperclip manages agent work through Runner and sandbox providers.
> - Product E2E runs paid work in disposable Daytona sandboxes.
> - A controller deadline cannot stop remote compute after the
controller crashes.
> - Inactivity cleanup does not establish an independent wall-clock
lifetime.
> - Daytona supports a lifetime in the creation request.
> - This change exposes that option in the Daytona driver and verifies
the provider expiry.
> - Ephemeral evals can retain a finite lifetime even when their
controller is unavailable.

## Linked Issues or Issue Description

Refs #17947 and #17978. No duplicate creation-lifetime PR was found.

**What happened?**
The ephemeral Product E2E fixture configures inactivity stop, archive,
and delete intervals. Ordinary task leases do not supply a requested
expiry. A crashed controller therefore has no confirmed wall-clock
sandbox lifetime for its cost bound.

**Expected behavior**
Each ephemeral eval sandbox must carry a provider-enforced lifetime from
creation. The driver must reject invalid bounds and reject a sandbox
whose provider expiry is missing, expired, or later than the configured
remaining lifetime.

**Steps to reproduce**
Acquire a Daytona lease from the ephemeral fixture. Inspect the creation
request and returned expiry. Before this patch, the request has no
lifetime and the lease has no expiry unless its caller supplies one.

**Paperclip version or commit**
Current source based on master at
4c314117d2.

**Deployment mode**
Source checkout and the bundled Daytona provider. Verification makes no
live provider or model calls.

## What Changed

- Add optional positive whole-minute `ttlMinutes` to the Daytona
environment configuration. Bump the bundled manifest version so
installed manifests refresh.
- Send the lifetime in image and snapshot creation requests. Read the
provider expiry within the configured liveness timeout before returning
the sandbox. Existing ownership-checked cleanup handles a failed expiry
check. A cleared optional field is treated as unset.
- Return the confirmed expiry on a new lease. Preserve an earlier
creation expiry when the caller requests a later deadline. Shorten it
for an earlier caller deadline.
- Set a 60-minute lifetime on the ephemeral Product E2E fixture. An
invariant checks that every selected attempt plus its acquisition budget
fits inside that lifetime.
- Keep omitted lifetime behavior and the separate warm continuity
fixture unchanged.

## Verification

- Before implementation, all 12 focused creation-lifetime regressions
failed.
- Full Daytona plugin suite: 470 passed, six live tests skipped. It
covers image/snapshot creation, invalid bounds before allocation,
missing/expired/excessive provider proof, cleanup, and both deadline
orders.
- Product catalog and operations contracts: 95 passed.
- Four review regressions failed before the fixes. They cover a cleared
field and stalled expiry reads in acquire, probe, and interactive setup.
- Standalone Daytona typecheck and build passed against its pinned SDK
0.203.0 and the freshly built plugin SDK.
- The pinned SDK forwards `ttlMinutes` in the create API. [Daytona
documents its wall-clock
semantics](https://www.daytona.io/docs/en/typescript-sdk/daytona/).
- Root workspace verification remains the fresh CI gate. Local installed
Runner exports are stale in this checkout.
- No live model request, sandbox allocation, credential creation,
spending-limit change, or schedule activation occurred.

## Risks

- A configured lifetime destroys the sandbox and its files at expiry,
including while active. Existing environment configurations omit it and
retain their current behavior.
- Ephemeral evals get 60 minutes so their longest declared 30-minute
attempt and five-minute acquisition budget fit. Future longer cases fail
the catalog invariant until their lifetime is reviewed.
- Provider expiry confirmation adds one read during configured creation.
No polling or background worker is added.
- Expiry confirmation uses the controller clock and fails closed without
a skew tolerance. Live qualification must verify the reported expiry. A
tolerance is deferred until there is measured provider evidence; it must
not silently extend the declared bound.
- These are contract tests. Actual Daytona creation, expiry proof, model
usage, and cleanup still need the remaining live qualification.

## Model Used

OpenAI Codex, GPT-6 based, with tool execution and extended reasoning.
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.1028.0-canary.6
2026-10-27 23:52:52 -05:00
DottaandPaperclip 5bf0142d45 fix(server): schedule Discord command registration from saved deadlines (#17557)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Chat connections register and verify provider commands in the
background.
> - Discord command recovery ran inside the recurring Gateway runtime
scan.
> - Its existing durable records already store verification and retry
deadlines.
> - This pull request gives command registration its own
shared-coordinator worker and scoped commit notifications.
> - Idle command work stops querying between real deadlines. Existing
command authority and recovery remain intact.

## Linked Issues or Issue Description

Refs #17554 and #17561. Both foundations have merged. This slice targets
master. Runtime discovery and the other chat maintenance duties remain
separate work.

**What happened?**

The chat runtime maintenance loop called Discord command registration on
every reconciliation. It repeatedly read durable command state even when
the next remote verification or retry was minutes away.

**Expected behavior**

Use committed producer changes and saved deadlines. Keep the existing
five-minute verification policy, Retry-After, uncertain-write
quarantine, namespace ownership, and credential fences. Do not add a
database table for the timer.

**Steps to reproduce**

Configure a Discord connection and let command registration settle. In
the parent revision, repeated runtime reconciliation still invokes
command recovery. This revision reconstructs command deadlines at
startup and removes that call from runtime reconciliation.

## What Changed

- Expose normalized deadlines from the existing registration store. Park
indefinite retries and invalid or foreign-owned records. Signal before
store-owned claims, receipts, and retry-result writes.
- Discover eligible endpoints in bounded pages. Refresh only affected
endpoint, connection, or company scopes after commits. Dispatch at most
25 due commands per pass with fair company rotation.
- Wire configuration, credentials, provider lifecycle/failure paths,
inbound activation, generic connection mutation/removal/health, access
revocation, and company deletion.
- Register the worker through the chat service and shared coordinator.
Preserve direct foreground setup calls. Refresh an existing local
Gateway through its current owner after command work.
- Preserve dirty work during drain and concurrent changes, back off
unresolved attempts, and join admitted provider work during shutdown.
- Document producer coverage, retained deadlines, supported writers,
verification failures, and remaining runtime/Cloud obligations in
`doc/idle-discord-command-registration.md` and its dated audit.

## Verification

Published head: `547fdf2139144e1e6484198278bf4bb0eade8794`. It normally
integrates master at `f8563d25077b17681ab6ef5949f7b07415a58ede`,
including landed health #17554 and company deletion #17561. Squash
ancestry caused merge conflicts; resolution applied this slice's exact
26-file owned patch from its recorded parent to pinned master. Every
other path matches master. Migration 0394 and the current lockfile are
preserved.

- **141 distinct targeted cases pass** on reconciled production source:
78 complete command-store, batching, coordinator and startup-timing
cases; 8 real automatic Discord and held-transaction Slack cases; and 55
complete startup/export and company-deletion cases. The 1,581 other chat
integration cases were deselected.
- Server typecheck and build pass. The company-deletion fixture
self-migrates an initially empty isolated database. The two Discord
fixtures use separate migrated clones; this is not a fresh-schema claim
for those fixtures. Signal-listener warnings remain recorded without
assertion failures.
- The parent integration preserves health and command notifications at
shared producer sites. It changes no provider behavior, schema or
coordinator contract. Prior producer, backlog, drain/resume,
malformed-hint, transaction, namespace, shutdown and retry regressions
remain in the complete command suite.
- [Landing compatibility
acceptance](https://github.com/paperclipai/paperclip/blob/547fdf2139144e1e6484198278bf4bb0eade8794/doc/idle-discord-command-registration.md#acceptance-after-the-company-deletion-parent-landed-october-27)
records current scope and the earlier failures. Older full-matrix or
combined-stack runs apply only to their stated revisions.
- Fresh exact-head Greptile, Ponytail if present and all CI are
required. No full local repository suite, live provider, Cloud alarm,
host suspension or savings claim is made.

## Risks

- Discord still has real five-minute verification and failure-retry
obligations. This does not prove host sleep or external alarm coverage.
- Runtime discovery, receipt-to-runtime projection, Gateway lease
renewal and persistent sockets remain separate. The remaining runtime
poll can still read command receipts; it no longer invokes the command
protocol.
- Process-local signals cover integrated writers. Independent SQL
writers and other replicas require an explicit wake contract. Existing
authorization and durable ownership checks remain authoritative.
- Refreshes coalesce with a 30-second minimum spacing. Saved work is
never discarded because a call returned without progress.
- No schema migration, new table, workflow or lockfile change is
introduced by this slice. Landed parent repairs are retained. The
receiver child must receive this integration before landing.

## Model Used

OpenAI Codex, GPT-6 family, with repository tools, code execution, and
reasoning. The exact serving version 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
- [ ] 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-27 23:32:24 -05:00
DottaandPaperclip 4c314117d2 fix(evals): bind active image identity and isolate routing checks (#17978)
## Thinking Path

> - Paperclip manages agent work through Runner.
> - Product E2E uses a content hash to identify its Daytona image.
> - The hash must include the active provider identity declaration.
> - The active Copilot fixture advanced past the manually listed image
inputs.
> - The runner routing test also captured later YAML steps as shell
commands.
> - This change binds the active fixture and stops shell extraction at
the next step.
> - Operators can verify image identity and routing against the current
source.

## Linked Issues or Issue Description

Refs #17937 and #17947. The related Copilot work includes #15563. This
change repairs the shared image contract; it does not add a Copilot
qualification claim.

**What happened?**
Two image tests fail because the active Copilot identity fixture is
absent from the image hash inputs. Four routing tests execute later
workflow YAML as shell commands after checkout and dependency steps were
added to the authorization job.

**Expected behavior**
The image hash must change when the active identity fixture changes. The
routing tests must execute only the selected routing step.

**Steps to reproduce**
Run the Daytona image and paid runner routing unit files on current
master. Six assertions fail before this patch. The same failures occur
on the clean 6b9e5f3a baseline.

**Paperclip version or commit**
Rebased onto master at 9b7d5b35eb.

**Deployment mode**
Source checkout. These tests make no provider requests.

## What Changed

- Read the active Copilot fixture version from the source-owned profile
manifest.
- Include that manifest and its active fixture in the image inputs. Keep
the historical entries and remove duplicate paths.
- Stop routing shell extraction at the next workflow step or job.
- Remove an obsolete comment that contradicted the current Docker build
context.

## Verification

- Focused image and routing tests: 18 passed after rebase.
- Existing image tests independently read the identity generator and
verify that changed fixture bytes change the image hash.
- Before this patch, six of those 18 tests fail on the unchanged source.
- Full Product support suite before rebase: 4,514 passed, one failed,
three skipped. The remaining macOS embedded Postgres bootstrap failure
also occurs on the clean baseline.
- The shared installed Runner workspace exports are stale in this local
checkout. Fresh CI remains the typecheck and build gate.
- No workflow, provider credentials, paid campaign, spending limit, or
schedule is changed.

## Risks

- The input set changes the image content ID. A fresh immutable image is
required for that content.
- The active fixture version must remain synchronized with the profile
manifest. The existing independent generator check fails if they drift.
- The extraction still depends on the workflow's current indentation.
The tests fail if the routing step cannot be found.

## Model Used

OpenAI Codex, GPT-6 based, with tool execution and extended reasoning.
The exact serving model ID and context window are not exposed in this
session.

## Checklist

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

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-10-27 23:29:43 -05:00
39279aa34f feat(ui): shared error, connectivity and query foundation for disconnects (#15754)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - The board reads API data and keeps the current task on screen.
> - A restart or temporary network failure can interrupt those reads.
> - Separate page error handlers can hide cached data or expose raw
server codes.
> - The app needs one connection state, readable error copy and a
consistent read policy.
> - This change provides that foundation and moves affected read
surfaces onto it.
> - The dependent write layer in #17960 preserves edits and submissions
across the same failures.

## Linked Issues or Issue Description

**What happened?**

Temporary API failures could replace loaded content with errors.
Different surfaces handled the same outage differently. Some showed raw
server codes. A successful query to an unrelated service could also
falsely report that Paperclip had recovered.

**Expected behavior**

Keep cached content visible. Show one connection banner during sustained
trouble. Confirm recovery through the Paperclip health probe or its
WebSocket. Retry transient reads and show readable errors for permanent
failures.

**Steps to reproduce**

1. Open a populated task or workspace page.
2. Interrupt API requests with a 503 or a dropped connection.
3. Keep an unrelated external request in flight.
4. Confirm that cached content remains and that the external result
cannot clear the outage.
5. Restore the API and check that reads refresh.

The write layer first merged into this feature branch in #15769 now has
its own dependent PR, #17960. This PR contains the shared foundation and
read changes. Merge this PR first.

## What Changed

- Classify API errors and provide readable error copy, including
non-JSON proxy responses and Retry-After handling.
- Use one connection store and health probe with bounded backoff.
Confirm recovery from the server health probe or live-updates WebSocket.
- Pause reads while disconnected, retry transient errors, and refresh
active reads after recovery.
- Keep cached data visible through shared query views and affected page,
panel and plugin read surfaces.
- Add one app-level connection banner and support the pending-write
count consumed by the dependent write layer.
- Add a query-error rendering guard. Call it directly from the existing
CI step. Update development documentation.

## Verification

- Historical-chat lookup now follows the same ready/stale roster state
as rendering. Three regressions fail before the fix; the six new cases
pass after it, including working Retry, fresh data, no-cache error,
permanent 403 and company isolation. All six focused query/recovery
suites pass 200 tests. Final-commit CI passes and Apex is 5/5 with no
unresolved findings. Canary Dry Run initially refused a preview version
that was already on npm. It passed after one rerun with fresh registry
metadata; no check was disabled.

- Integrated current master and retained both transcript interest
registration and connectivity reporting on socket open. The seven
focused recovery/query suites pass 288 tests, and UI typecheck and
production build pass. All 9,451 UI tests across 799 files pass on the
merge commit. Final-commit CI passes and Apex is 5/5 with no unresolved
findings.

- Current head `70d9335d732219352ef0f98414439766bbcb33df`: all hosted CI
checks pass. Apex is **5/5** on that head with no unresolved findings.
The branch has no merge conflict. GitHub still requires code-owner
approval.

- The foundation passes 9,430 UI tests in 804 files. After integrating
current master page paths, 190 focused page tests pass.
- Two unrelated-success regressions fail before the latest fix. With the
fix, 62 focused UI tests, all six guard tests and UI TypeScript pass.
- The composed foundation and write layer pass **9,505 UI tests in 808
files**, UI TypeScript, a production UI build, and query-error, token
and map guards.
- A real Chromium journey on the composed source injects a 503 during
title save. The loaded task stays visible; one reconnect banner appears;
the edit saves after recovery; another task stays unchanged; the saved
title survives reload.
- Full recursive local checks were not repeated because Runner
compilation exhausted local disk during another repair. Hosted checks
must pass before merge. No new staging deployment is claimed.

- Latest review follow-up: a cached CaseDetail now survives a failed
HTTP 429 refresh. Its page regression fails before the fix and passes
after it. Eighty focused foundation tests, UI TypeScript, build and
guards pass after that change.
- Earlier CI evidence is retained: several foundation jobs received a
runner shutdown signal together. The write-layer head also failed an
unchanged Runner descriptor close test with `provider_transport_failed`.
The same Runner source passed that suite in the foundation run. New CI
runs cover the updated heads; no check or assertion was weakened.

## Risks

- Shared retry defaults change the time before transient read errors
appear. Permanent errors still fail promptly.
- ApiError.message now contains readable copy. Callers that compare raw
codes must use ApiError.code.
- Cache success can come from another service or local data. It must not
confirm Paperclip recovery.
- Durable writes are reviewed separately in #17960. This PR does not
change database or mutation contracts.

## Model Used

Anthropic Claude Opus 5.5 (`claude-opus-5-5`) produced the original work
with tool use. OpenAI Codex, GPT-6 family, assisted with restoration,
integration, tests and review fixes. The Codex session does not expose
its exact serving 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: devinfoley <139239+devinfoley@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Paperclip <noreply@paperclip.ing>
Co-authored-by: Amy (Opus) <claude@users.noreply.github.com>
2026-10-27 21:22:07 -07:00
DottaandPaperclip 9b7d5b35eb fix(evals): refresh forecasts from complete request receipts (#17975)
## Thinking Path

> - Paperclip coordinates agent work through Runner.
> - Scheduled Product E2E campaigns need measured cost and time
forecasts.
> - The saved forecast samples came from October 21.
> - The October 27 qualifications retain final usage for all 19 model
requests.
> - The Claude measurements are hosted; the Codex measurements are
local.
> - This change refreshes the samples and keeps measurement hosts
separate.
> - Operators can inspect the latest evidence without treating it as
current qualification or an invoice.

## Linked Issues or Issue Description

Refs #17127 and #17946.

**What happened?**
The scheduled forecast still uses the older pilot amounts. It reports no
hosted measurement and does not record the measurement host per sample.

**What did you expect to happen?**
The forecast must retain the latest complete model receipts and their
source hashes. It must keep local and hosted timing cohorts separate. A
changed definition must remain unqualified.

**Steps to reproduce**
Prepare the daily or weekly forecast from the default branch. Inspect
its saved measurement date, totals, and hosted fields.

## What Changed

- Refresh four samples from two intact request ledgers and four retained
Product results.
- Record measurement hosts, final request counts, and original campaign
outcomes.
- Add historical hosted totals. Current hosted totals still require
matching evidence for every selected cell.
- Keep hosts in separate per-cell cohorts. Preserve definition drift and
unknown slow-tail estimates.
- Document the model-cost scope and timing limits.

## Verification

- Forecast and scheduled-preflight tests: 33 passed.
- The extraction replays both hash-checked ledgers, requires final
receipts, and checks the retained pricecards. The four samples cover 19
final requests.
- Daily historical model subtotal: $0.428650100; summed attempt time:
107.286 seconds.
- Weekly historical model subtotal: $0.793676500; summed attempt time:
158.093 seconds. The Codex samples are local.
- Full Product support suite at the initial head: 4,510 passed, seven
failed, three skipped. A clean 6b9e5f3a baseline with the same installed
dependencies reproduces the same seven failures: two Copilot image
assertions, four workflow-selection shell assertions, and one database
startup test.
- Product typecheck also fails on that clean baseline because the shared
installed Runner workspace exports are stale. The fresh CI build remains
the typecheck gate.
- No provider request, new live campaign, budget change, or schedule
activation is part of this PR.

## Risks

- These are successful-attempt measurements, not a prediction of failure
frequency or a campaign invoice.
- The feedback source fingerprint changed after the samples.
Current-compatible totals remain unknown; no historical fingerprint is
rewritten.
- Hosted worker cases passed, but their original workflow failed during
report dependency setup. That outcome stays visible.
- Hosted detection deliberately accepts only the measured GitHub Ubuntu
environment. Other host labels remain unqualified until declared with
their own evidence.
- The weekly selection still has no complete hosted timing measurement.
Infrastructure, storage, and observability charges stay separate from
model spend.

## Model Used

OpenAI Codex, GPT-6 based, with tool execution and extended reasoning.
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.1028.0-canary.5
2026-10-27 23:13:08 -05:00
DottaandPaperclip f8563d2507 fix(server): remove chat endpoints before company agents (#17561)
## Thinking Path

> - Paperclip manages agent companies and their connected chat channels.
> - A company deletion must remove dependent data in one transaction.
> - Chat endpoints reference assigned agents with a restrictive foreign
key.
> - The current deletion order purges agents before those endpoints.
> - This pull request removes company endpoint rows and chat history
before issue and agent deletion.
> - The existing lifecycle checks, company isolation, and rollback
remain intact.

## Linked Issues or Issue Description

**What happened?**

Deleting a company with a chat endpoint fails on the endpoint's
assigned-agent foreign key. The failure was found while verifying the
company-deletion wake in #17557.

**Expected behavior**

Company deletion removes endpoint dependencies before their referenced
issues and agents. It preserves other companies and global Discord
ownership tombstones. A later failure rolls back the cleanup.

**Steps to reproduce**

Create a company, an agent, and a Discord endpoint assigned to that
agent. Complete agent termination, then delete the company. The old
order fails with the restrictive endpoint-to-agent foreign key.

**Paperclip version or commit**

This prerequisite includes merged #17554 at `94a780286f` and supports
#17557. Only four cleanup-owned paths differ from that landed parent.
Related #16465 covers the deletion feature flag, not dependency order.

## What Changed

- Add a chat-owned company-deletion participant using the existing
transaction contract.
- Remove only the requested company's endpoints before issue deletion
and the agent lifecycle participant.
- Preserve namespace tombstones and existing restrictive foreign keys.
- Add real PostgreSQL regressions for ordering, isolation, and rollback.
- Migrate a validated disposable external database before fixture use,
use the shared PostgreSQL bootstrap budget for setup, and remove
fixture-owned Discord tombstones during test teardown.

## Verification

Published head: `9766cc61c42fe0f73e241bbe99f9d9f145f4b11c`. Parent
#17554 is merged. This branch reconciles the actual landed health squash
`94a780286f` and targets master. Fresh reviews and CI are required for
this exact head.

- The latest review requested the repository's shared
EMBEDDED_POSTGRES_TEST_TIMEOUT_MS (90 seconds) for bootstrap. This
replaces the earlier suggested 30-second limit. All six existing cases
pass on another initially empty database with that constant; no test
assertion or production code changes. The documented contention budget
is repository evidence, not a locally reproduced 40-second bootstrap
failure.
- All six complete cleanup-removal service cases pass on an initially
empty dedicated PostgreSQL 17 database with the updated health parent.
- The pre-fix real endpoint-deletion case failed with missing-table
errors because external fixture setup skipped migrations. Applying
pending migrations before client use fixes that failure; no assertion is
removed or weakened.
- An independent query after the complete suite finds zero fixture
ownership tombstones. Production company deletion still preserves those
records.
- Cases cover endpoint removal before issue and agent references,
other-company isolation, namespace ownership preservation, and rollback
after a later failure. Both product regressions failed before the
original ordering fix.
- Server typecheck and build pass with the updated parent and fixture
repair at `21be75d2b0`. The landed-parent reconciliation changes only
the lockfile; all source and test bytes remain identical. All six cases
pass again with the new installed dependency patch. The initial
scope-proof command raced a shared `origin/master` update; a new proof
pins the actual landed parent and confirms the four-file scope. A later
native-checkpoint merge `09ad9adce2` has no overlap with these four
files.
- [Owning acceptance
document](https://github.com/paperclipai/paperclip/blob/9766cc61c42fe0f73e241bbe99f9d9f145f4b11c/doc/company-chat-deletion.md#current-parent-acceptance-october-27)
retains the failing baseline, parent scope, and limitations. No full
local repository-suite or deployed suspension claim is made. Older
inherited gateway/combined-stack evidence is separate from this
four-file fix.

## Risks

- The endpoint cleanup shares the caller's transaction. A later deletion
failure must restore the endpoint; the regression verifies that
boundary.
- Existing retained voice-history restrictions and external provider
teardown policy remain unchanged. This fix does not bypass restrictive
foreign keys.
- No migrations, lockfile changes, or workflow edits.

## Model Used

OpenAI Codex, GPT-6 family, with repository inspection, code edits, and
tool-assisted tests. The exact runtime variant and context-window size
are not exposed in this session.

## Checklist

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

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-10-27 23:06:31 -05:00
Dotta 81bba1dd0d fix(evals): scope design approval claims to contrast clauses 2026-10-27 23:00:30 -05:00
Dotta 89063699af fix(evals): recognize explicit design revision ordering 2026-10-27 23:00:29 -05:00
SudheerandClaude Opus 5.5 70c8646337 fix(ui): drop top margin and border on first contextual sidebar section (#17412)
The first section in the contextual sidebar rendered a leading top
margin and divider with nothing above it. Use first: variants so only
sections that follow another section get the spacing and border.

<!-- 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 board UI has contextual sidebars, such as Skills, Apps, and
Agent
> - These sidebars share one set of style constants in
`contextual-sidebar-styles.ts`
> - Each section in the sidebar has a top margin and a top border to
separate it from the section above
> - The first section has no section above it, but it still shows the
margin and the border
> - This pull request adds `first:` variants to the section style
> - The first section now sits flush at the top, and the other sections
keep their divider

## Linked Issues or Issue Description

**What existing behavior does this improve?**

The section style in the contextual sidebar. It adds a top margin and a
top border to every section.

**Subsystem affected**

UI (`ui/src/components/contextual-sidebar-styles.ts`)

**Current behavior**

The first section in the sidebar shows a top margin and a divider line.
Nothing is above it, so the divider looks wrong and wastes space.

**Proposed behavior**

The first section has no top margin and no top border. Each later
section keeps its margin and divider.

**Reason and benefit**

The sidebar looks cleaner at the top. The change is small and uses only
existing design tokens.

**Breaking changes**

None.

## What Changed

- Added `first:mt-0 first:border-t-0` to
`contextualSidebarStyles.section` in
`ui/src/components/contextual-sidebar-styles.ts`.

Before: 
<img width="585" height="410" alt="Screenshot 2026-10-24 at 10 14 36 AM"
src="https://github.com/user-attachments/assets/12c35f5f-7993-4fdb-89b2-df3394859bf8"
/>
After:
<img width="560" height="377" alt="Screenshot 2026-10-24 at 10 14 24 AM"
src="https://github.com/user-attachments/assets/92e1f7ab-f4c0-48ac-832a-a3726770deac"
/>


## Verification

- Run `pnpm check:token-gates`. It passes.
- Open a page that uses a contextual sidebar, such as Skills or Apps.
- Check that the first section has no top gap and no divider.
- Check that the later sections still show their divider.

## Risks

- Low risk. The change affects only the spacing and the top border of
the first sectio
- Several sidebars share this style, so check each one: Apps, Skills,
Agent, and Chat detail.

> 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

- Provider: Anthropic
- Model: Claude Opus 5.5 (`claude-opus-5-5`) made the commit. Claude
Sonnet 5.5 (`claude-sonnet-5-5`) helped review the change afterward.
- Capabilities: tool use and code execution in Claude Code (CLI).
- The one-line style change is human-authored.

## 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 puub.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
- [ ] 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: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-27 20:42:28 -07:00
Dotta 22dd6a1280 test(evals): report effective project-defaults timeout policy 2026-10-27 22:36:30 -05:00
Devin FoleyandPaperclip c9213d1be4 fix: send saved queued messages after Stop (#17959)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - People can save follow-up messages while an agent runs.
> - Stop preserves those messages and stops the active execution.
> - The queue removed its delivery controls when that execution ended.
> - Native admission also refused an explicit resend of older queued
input.
> - This change adds Send for a stopped queue and records fresh board
intent.
> - The saved message can continue through normal cleanup and admission
checks.

## Linked Issues or Issue Description

**What happened?**

A person queued a message with a screenshot while an agent was starting.
Steering was not yet available. They stopped the run. The message
remained visible, but no control could send it. Native queue delivery
also rejected this transition.

**Expected behavior**

A stopped queue offers Send. The click preserves message IDs, content,
attachments and original authors. It starts at most one eligible
continuation. Stop remains effective until the person gives new
direction.

**Steps to reproduce**

1. Start a native task and queue a second message.
2. Stop the active run before it consumes that message.
3. Open the task after cleanup. Observe the saved message with no send
control.

Refs #16965 for the queue-control change and #15015 for stopped
conversation recovery. No open repair for this exact transition was
found.

## What Changed

- Show Send for a saved deferred queue with no active run.
- Accept the existing board queue action for a stopped native target.
Keep live native interruption restricted.
- Use the server-recorded click time to authorize older native messages.
Reject stale, malformed and wrong-actor intents.
- Reuse normal queue dispatch, revision checks, cleanup proofs and
execution admission, including a failed native predecessor after a
verified Send.
- Ignore a fully committed, successful recovered export when admitting a
fresh message, while retaining the wait for results still committing.
- Honor an applied `/new` conversation boundary while retaining native
execution holds until the existing stop and cleanup checks verify them.
Workspace holds also survive reset. Check the newest failed or cancelled
native execution even when older recovery actions exist.
- Keep native automatic delivery separate from the explicit Send action.
Update execution and access documentation.

## Verification

- Meaningful regressions failed before the fixes: stopped queues lacked
Send, native admission refused fresh intent, cleanup and dispatch
receipts were missing, deferred rows disappeared, live plan Interrupt
rejected its own receipt, and Agent Chat `/new` inherited an old
non-workspace execution hold.
- Six assembled-wakeup cases fail before the reset cleanup fix. All 11
reset/history cases pass after it: live processes, missing identity,
quarantined cleanup, remote leases and live controllers remain held;
verified cleanup proceeds and retires the hold. Two more cases fail
before the fallback fix and pass after it: Send verifies a stopped or
live native predecessor despite a later reset receipt and no recovery
record.
- **525 server tests pass** across seven queue admission, route,
dispatch, envelope, provenance, blocker and conversation files. **343
queue/thread UI tests** also pass. Server/UI TypeScript, token and map
guards pass. The final scoped server typecheck also builds native Runner
successfully.
- The latest regressions prove that completed recovered exports permit
fresh input, and clearing conversation history still requires old native
stop and cleanup verification; an unsafe workspace still blocks after
`/new`; failed native Send reaches actual continuation dispatch with the
original queued comment. A result still being committed remains
deferred. History plus a newer Stop cannot hide a missing
process/controller/lease receipt.
- The real Chromium Stop/Send journey passes on current head
`75fa5e7222c59f43ff7ac326e81093bc9da28330`: queue a follow-up, Stop,
reload, explicitly Send, then verify exactly one useful response and no
live run. Earlier browser journeys cover legacy Interrupt, interruption
during a write and Stop followed by a new direction. These use an
isolated app/database and controlled ACP fixture, not an external AI
account or a staging deployment.
- Negative cases retain actor, company, issue, assignee, queue and
cancellation-receipt bindings; cleanup/process/workspace/controller
holds; approvals; pause and budget gates. Typed responses keep their
original resolver and immutable result.
- Full local recursive typecheck stopped in unchanged Rust Runner
compilation with ENOSPC, so the chained full tests/build did not run.
All hosted CI gates pass on final commit
`75fa5e7222c59f43ff7ac326e81093bc9da28330`, including typecheck, tests,
build and E2E. Apex review on that commit is 5/5, with no unresolved
findings. Earlier unrelated CI failures involved PostgreSQL
fixture-cleanup deadlock and an unchanged decision-expiry deadline
assertion; the latter's 20 cases pass locally without source changes. No
assertions or limits were weakened. Local resource cleanup was limited
to this task's verified completed test processes and rebuildable npm
caches.

## Risks

- Send can authorize a new turn for a saved message after Stop. A Send
click must be newer than the stopped execution; a live plan Interrupt is
bound to the cancellation receipt produced by that same click. It does
not imply that cleanup finished or that an external action is safe to
replay.
- The existing endpoint and intent format are reused. No schema or
credential change is required. Live native steering and legacy
interruption keep their existing paths.

## Model Used

OpenAI Codex, GPT-6 family, with reasoning, repository inspection, tool
use and code execution. The session does not expose the exact serving
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-27 20:34:14 -07:00
Devin FoleyandPaperclip 6102f8e82c fix: pass healthy managed Runner connection tests (#17965)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - The board tests an agent's selected runtime and AI account.
> - Cloud prepares and verifies the managed Runner runtime before
execution.
> - Its remote ACPX preflight reports that deferred step as a warning.
> - The test keeps the warning after the selected account passes its
hello probe.
> - The board then asks the user to fix a healthy connection.
> - This change makes that specific managed step informational after
account verification.

## Linked Issues or Issue Description

**What happened?**

A Cloud agent's Claude connection test passes with Legacy. With Runner,
the same account completes the Claude hello probe but shows "Connection
needs attention." The only warning says that remote runtime preparation
must occur before launch.

**Expected behavior**

A verified managed connection passes when its only warning concerns
runtime preparation that Paperclip performs before execution. Failed
authentication and actionable runtime checks retain their results.

**Steps to reproduce**

1. Select a working Claude subscription on a Cloud-managed sandbox.
2. Select Runner and run the connection test.
3. Observe a successful Claude hello probe and a warning result.

Related: #17961 covers managed OpenRouter model verification. #15880
adds persistent computer runtime interfaces. Neither changes this Cloud
connection-test status.

## What Changed

- Recognize the deferred ACPX runtime check after a provider hello or
live API-key verification succeeds.
- Report that check as informational for Cloud-managed sandbox
connections.
- Preserve every other warning and error, including unexplained warning
results.
- Add service regressions and document the test/launch boundary.

## Verification

- Red: the healthy managed-Claude case returned `warn` after a
successful hello. The regression fails before the change and passes
after it.
- **116 tests pass** across connection verdicts, environment-test HTTP
routes and adapter registration. Scoped server TypeScript and the server
build pass, including the native Runner build.
- Negative cases cover rejected credentials, missing hello receipts,
missing runtime packages, actionable or unexplained warnings,
self-hosted instances, SSH targets and unexplained provider warning
results. API-key success requires live provider re-verification.
- Operator evidence confirms that the reported test lease was released
with cleanup successful. The agent's saved adapter is Legacy. No saved
account, agent or environment setting was changed.
- A clean local install hit a frozen-lockfile `patchedDependencies`
configuration mismatch. The scoped checks reuse installed workspace
dependencies. The final commit has passing hosted CI, including
clean-install typecheck, tests and build, and Apex 5/5 with no
unresolved findings.
- A cold HTTP-suite module load reached the 30-second setup limit while
other checks ran. All 54 HTTP cases pass on retry, and the full focused
run passes 116 tests without changing assertions or time limits.
- No staging deployment is claimed. This change classifies the
connection-test result; it does not claim that a native Runner hello
turn was performed.

## Risks

- This status change is limited to a verified Cloud-managed sandbox ACPX
connection and the exact deferred check code. The provider's successful
receipt is required.
- Runtime package preparation and verification still execute before
agent work. A connection test does not replace those launch checks.
- There is no schema, permission or credential change. Local, SSH and
plugin task probes keep their existing verdicts.

## Model Used

OpenAI Codex, GPT-6 family, with reasoning, repository inspection, tool
use and code execution. The session does not expose its exact serving
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
#` 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-27 20:34:10 -07:00
DottaandPaperclip 6cc765bd81 feat(live): deliver recoverable transcripts to interested views (#17456)
## Thinking Path

> - Paperclip should show live agent output without repeating
presentation work for every view.
> - Execution, acknowledgements and durable checkpoints must remain
independent of browser interest.
> - The server already owns authorization and redaction at delivery.
> - A shared browser connection can declare which visible runs need full
transcripts.
> - Catch-up must handle subscription races, disconnects, terminal
output and slow consumers.
> - This PR delivers the backend and UI contract together without a
database migration.

## Linked Issues or Issue Description

**What existing behavior does this improve?**

Visible transcript consumers receive recoverable output through one
shared browser connection.

**Current behavior**

Independent views can create duplicate connections, presentation work
and recurring history reads. A subscription race or filtered native
history can lose the saved tail.

**Proposed behavior**

Negotiate run interests, subscribe before catch-up and retain
independent canonical recovery cursors. Keep lightweight lifecycle and
attention events available without full transcript delivery.

PR 4 of #17097 → #17439 → #17455 → #17456. The runtime feature is
independent of hot-upgrade recovery; the stack order is for review
convenience.

## What Changed

- Add additive WebSocket capability negotiation, replacement interests,
revision acknowledgement and resynchronization notices.
- Reference-count visible consumer interests on one company-scoped
browser connection. Preserve older-client/server behavior.
- Reuse canonical structural/current-user/registered-secret redaction
for plugin run notifications through the same bounded delivery queue.
Keep producer and uninterested streams free of recipient lookups.
- Refresh application queries after the matching recovery
acknowledgement, including one follow-up after an older in-flight read.
Ordinary interest acknowledgements add no refresh.
- Keep authorization and redaction at delivery. Browser interest cannot
change harness execution, PRP ACKs, checkpoints, accounting or canonical
logs.
- Deduplicate by sequence and log identity. Catch up terminal output and
saved tails without recurring reads during healthy negotiated streaming.
- Bound delivery to 1,000 items and 1 MiB. Overflow requires
resynchronization; persistent congestion closes the connection.
- Preserve compact-history expansion from current master across
paginated catch-up. Snapshot the original read window before React can
defer its update.

## Verification

On current source `f6710f0b3c`, Linux [job
122604880503](https://github.com/paperclipai/paperclip/actions/runs/40624101891/job/122604880503)
executes all five run-read permission cases successfully (2.574
seconds), including grant and revocation on the same connection. Its
shard passes all 2,430 cases.

Current [server-shard job
122604880416](https://github.com/paperclipai/paperclip/actions/runs/40624101891/job/122604880416)
has 1,513 passes, one failure and three skips: an unchanged nested-clone
expiration/restore test exceeds its 15-second deadline. The preceding
`5efc6c48bf` source has identical non-document bytes; [its corresponding
job
122601359272](https://github.com/paperclipai/paperclip/actions/runs/40623017917/job/122601359272)
passes all 21 nested-clone cases, including that case in 9.505 seconds.
The exact timing cause is unproven. The single diagnostic [retry job
122609332597](https://github.com/paperclipai/paperclip/actions/runs/40624101891/job/122609332597)
passes all 21 nested-clone cases (61.316 seconds), including the
formerly timed-out case in 7.003 seconds, and all 1,514 shard cases
(three skips). The failure remains recorded; no timeout or assertion was
changed.

After the server squash merge and qualification retarget, all 50 focused
server cases and all 91 focused UI cases pass again, with both
typechecks and token gates. Runner vendor preparation rebuilds current
master inputs before those tests. This source needs fresh CI and
reviews; prior CI and browser receipts do not qualify it by inference.

Current candidate `f6710f0b3c` now targets master `6987c2f20b`, after
merged #17097, #17439 and #17455. Its diff contains only transcript
delivery and its documentation. It adds no database migration.
Retargeting changes only the evidence document; all production and test
code is byte-identical to `5efc6c48bf`.

On the eighth integration, all 50 focused server delivery cases and all
91 focused UI cases pass, with both typechecks and token gates. The
following 35-case receipt belongs to the earlier delivery correction.
Four low-queue authorization/decoration stall variants and the
late-rejection case fail before correction. They now verify the
five-second read deadline, old and negotiated clients, revisions that
cannot reset the deadline, unaffected sibling connections, rejected late
results, and timer cleanup. The first combined toast run has four
loopback EPERM failures and 31 passes; its permitted repeat passes all
35. Earlier 28-case evidence excluded the toast file.

The permission correction requires the current HTTP company-scope
transcript permission, plus task access, for both native events and
legacy logs. Prior Linux source `49a8783e9b`, job 122549913643, executes
all five run-read cases, including grant/revocation on the same
connection, successfully. That source placed this file in server shard
11; later shard assignments can differ and must be checked against their
actual inventories. The older `405bedd189` receipt retains a separate
scheduled-retry teardown race and inherited fixture collision; neither
is waived. The new head must pass again in Linux CI.

The seven extracted stream-recovery tests preserve their assertions. All
39 related legacy/native cases, UI typecheck and token gates pass after
restoring the initially missed fixture helper. Earlier full workspace
build/typecheck and Chrome journeys at `445a76563c` cover two views,
company switches, reconnect, terminal catch-up, reload and zero
recurring healthy transcript reads. Those browser receipts are
historical source evidence and do not qualify this new head by
inference. The [qualification
record](https://github.com/paperclipai/paperclip/blob/f6710f0b3c84c6fdb2021df67206261b446dfc97/doc/plans/2026-10-22-hot-upgrade-qualification.md)
retains exact earlier UI/history, source-boundary and cleanup failures
with their fixes and limits.

The workload-cost test preserves bounds and authorization callback
counts for zero interests, one viewer, multiple browsers and a slow
viewer. Its socket congestion is simulated. It measures neither SQL nor
network costs. Current permission checks and the final hosted
active-agent/viewer matrix remain unmeasured; no production savings are
claimed.

Fresh exact-head CI, legacy status, completed Greptile 5/5, resolved
feedback and ordinary merge eligibility remain required.

The earlier recipient corrections pass all 47
registry/plugin/delivery/WebSocket/toast cases and all 174 UI
provider/recovery/interest cases, both typechecks and token gates on
source `b202e59a25`. A real bus/host-service test registers a synthetic
run secret through the production registry and reproduces its raw
notification before the fix; native/legacy/final notifications now
redact it, disposal prevents late worker notification. A later P1 review
reproduces lost final notifications on settings-read and
secret-resolution failure. Both cases fail before correction. Any
delivery failure or subscription timeout now sends one content-free
stream error and removes the plugin subscription. It never changes the
agent execution or run status. Later events start no new redaction
reads. The final integrated six-file server lane passes all 50 cases,
with server typecheck and token gates. Existing browser delivery
behavior is unchanged. Storage and secret-provider seams are scripted.
Two real React Query/provider regressions first miss a run during
resync; both now refresh after the valid replacement ACK, including
pending-read and stale-scope cases. The prerequisite qualification batch
passes all 118 cases and E2E typecheck after master integration. Fresh
CI, security scan and reviews remain pending on this head.

The contribution-rule review correction removes 104 explanatory comments
introduced by this slice and keeps the ordering, deadline and
plugin-delivery explanations in the delivery document. Existing comments
and functional test/lint directives remain. All edited source files have
identical parsed non-comment tokens before and after the change. All 50
server delivery cases and all 91 cases in six affected UI suites pass,
along with token gates. The new head requires fresh CI, security and
review.

## Risks

A slow or disconnected viewer must resynchronize from authorized
canonical history. It may see a display gap until catch-up completes.
Company changes and revoked access must remove delivery interests. This
slice adds no database migration and cannot change execution or recovery
authority. Full transcript delivery evaluates current company-scope
permission per delivery. Active plugin recipients also perform canonical
redaction reads; viewer-load database costs on this final source remain
unmeasured.

## Model Used

OpenAI GPT-6 through Codex, with reasoning, repository tools and code
execution. The runtime does not expose a more specific 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
- [ ] 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.1028.0-canary.4
2026-10-27 22:23:30 -05:00
DottaandPaperclip f52da40f08 fix: resume queued turns after maintenance (#17967)
Keep an accepted turn's starting input in task history, show its admission wait, and resume existing queued runs promptly when maintenance ends or expires.

Verified with behavioral red/green regressions, real PostgreSQL and process execution, browser/native Runner acceptance with a deterministic provider, workspace typecheck, production build, and current-head CI/review.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-27 22:20:03 -05:00
DottaandPaperclip 6b9e5f3a80 fix(evals): enforce qualified ACPX profile admission before paid turns (#17964)
## Thinking Path

> - Paperclip coordinates agent work through Runner.
> - Controlled evals route model calls through a budget gateway.
> - The definitions pin each ACPX runtime identity.
> - A stale qualified profile currently reaches a paid turn before
scoring rejects it.
> - The Runner CLI already checks an exact expected profile before it
creates a provider.
> - This change forwards that existing admission argument through the
controller.
> - Profile drift can then stop before model spending.

## Linked Issues or Issue Description

Refs #17943 and #17929.

**What happened?**
The worker in run 40618022700 passed all four behavior checks and
retained three final request receipts. Its grader then rejected the old
Claude SDK pin. The controlled wrapper could not pass the existing
`--expected-acpx-profile` argument to the built CLI.

**What did you expect to happen?**
The built CLI must reject a stale expected profile before provider
creation.

**Steps to reproduce**
Run a controlled ACPX cell with a definition that pins a different SDK
from the built Runner. The old wrapper accepts only request and output
arguments. It cannot enforce the profile admission supplied by updated
definitions.

**Paperclip version**
The observed run used e4b30163bb.

**Deployment mode**
The controlled GitHub Actions Runner protocol workflow.

## What Changed

- Forward bounded expected-profile JSON through the controlled wrapper
to the same built CLI.
- Reject invalid objects, oversized arguments, and profiles on non-ACPX
requests before opening evidence.
- Exercise a real child boundary and the actual qualified Claude CLI
admission gate.
- Document the definition/controller compatibility requirement.

## Verification

- Controller suite: 77 tests passed. The new regressions fail against
the original wrapper.
- Hosted and portable controller suites: 8 tests passed.
- Actual eval-session CLI contract suite: 39 tests passed. A stale
qualified Claude SDK never creates a provider service.
- Runner package typecheck passed.
- The non-ACPX rejection guard also passed its focused regression after
review.
- No live provider request was made for this change.
- Full repository checks and current-head reviews run on this PR.

## Risks

- Updated definitions require this wrapper before they can pass the new
argument. Merge the controller first.
- Profile identity remains owned by the built Runner CLI. The controller
only forwards its existing argument.
- Existing callers that omit the argument retain their current behavior.
- Optional review suggestions to duplicate the expected-profile hash
into controller evidence and add a full built-CLI/controller integration
case are deferred. The pinned definition revision retains the expected
profile, and both controller entrypoints plus the actual CLI admission
boundary are covered. A compatibility error fails closed without a paid
fallback.

## Model Used

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

## Checklist


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

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-10-27 21:59:20 -05:00
DottaandPaperclip 6987c2f20b test(upgrades): qualify controller replacement with immutable artifacts and phase evidence (#17455)
<!-- entire-trail-link-start -->
https://entire.com/gh/paperclipai/-/trails/105/changes/paperclip/105
<!-- entire-trail-link-end -->

## Thinking Path

> - Paperclip needs evidence that an admitted execution survives a
main-server replacement.
> - Runner mechanics and server adoption belong to #17097 and #17439.
> - A healthy HTTP endpoint does not prove recovery of the original
execution.
> - Qualification must identify the serving artifact, natural ownership,
authenticated attachment and resumed processing separately.
> - It must also retain failed runs and measure normal-operation costs.
> - This PR extends the existing qualification machinery and acceptance
record.

## Linked Issues or Issue Description

**What existing behavior does this improve?**

Operators can assess upgrade continuity from phase evidence tied to
exact artifacts and profiles.

**Current behavior**

A same-artifact restart or synthetic executor pass cannot establish
different-artifact upgrade and rollback support. Idle SQL gates also do
not measure active-run capacity.

**Proposed behavior**

Use immutable A/B artifacts and strict phase receipts through the
existing supervisor. Preserve failed evidence and add measured
before/after workload costs.

Builds on merged #17097 and #17439. The base is now `master`. #17456
follows for review convenience. This PR lands qualification machinery
and the evidence record. The remaining hosted gates stay open for
deployment qualification; merging this machinery does not claim those
experiments passed.

## What Changed

- Extend the main-server supervisor and installed-artifact verification
for actual serving revisions, forward migrations and compatible
rollback.
- Distinguish HTTP readiness, natural ownership, authenticated
attachment, resumed processing and backlog settlement.
- Retain the original reconnect grace and execution identity checks.
Never substitute a new task or edited lease for continuity.
- Reuse real-harness and Daytona qualification paths, with exact profile
and artifact provenance.
- Bind current Copilot attestation inputs in the Daytona image
fingerprint.
- Keep one acceptance record, including both failed file-only stress
phases and the final passing bounded-pool comparison.

## Verification

After retargeting to master, all 158 focused qualification cases across
13 files pass, with E2E typecheck. The first 12-file batch has four
report-lock test failures and 133 passes. Master #17811 had committed
the exact already-approved output lock, while that fixture assumed HEAD
must be the uncorrected input. The fixture now checks both pinned forms,
executes the committed-lock path, and reconstructs the pinned input to
retain all rejection tests. The production helper, policy hashes, patch
and dependency resolution are unchanged. The corrected batch explicitly
includes both process-preservation suites; the prior 146-case receipt
has its own source and selection.

Current candidate `8f1d6ec02f` integrates master `09ad9adce2`, including
the merged server slice. Its diff contains only qualification code and
documentation. The [qualification
record](https://github.com/paperclipai/paperclip/blob/8f1d6ec02f5bf6c90e7b27da8156953cabd9a180/doc/plans/2026-10-22-hot-upgrade-qualification.md)
is the acceptance ledger and retains source-attributed failures and
hosted limits.

On the eighth integration, all 146 cases across 12 focused qualification
files pass, including report-lock preparation, workflow security and
workflow targeting. E2E typecheck passes. The earlier 118-case result
remains attributed to its prior source. The first sandbox invocation has
117 passes and one failure because process inspection was denied during
inert fixture cleanup. The permitted repeat passes all 118 and a
targeted process check finds no remaining fixture daemon. The earlier
96-case receipt remains source-attributed in the ledger. The latest two
review regressions first fail: an intermediate replacement can cite
another runner/session despite a valid final step, and malformed receipt
JSON aborts evidence packaging. Each replacement now binds
run/company/issue/runner/session, and corrupt receipts retain explicit
invalid metadata plus sanitized diagnostics while other logs and
receipts still package. These checks prove qualification machinery with
injected supervisor operations, configuration subprocesses and real
filesystem packaging. They do not qualify a hosted harness.

Three request-reader cases, 14 artifact/configuration/cache/history
cases, and three lost-partial-receipt cases fail before their respective
corrections. The final collector preserves sanitized startup, readiness
and recovery phase receipts through packaging and temporary-root
deletion. Earlier embedded-Postgres initialization, report-catalog
drift, CI scheduling/cleanup failures and fixture collisions remain
recorded with their corrections or limits. The previous Greptile service
error is retained as historical review evidence, not a current review
pass.

The record includes prior source `9bb9d3417e`'s actual Linux
contention/fairness successes and the ordinary-warm regression proof
from the server slice. The historical 300-session component campaign
passes four after phases and retains earlier burst failures. Those
component costs do not establish hosted capacity. The hosted API-only
pair has zero agents/viewers, fails both absolute latency gates and the
candidate memory gate, and does not complete the active-agent/viewer
matrix.

The strict ten-agent same-artifact restart remains attributed to its
original artifact. It does not qualify this updated stack. Actual
A→B/B→A, the normal drain-free Cloud rollout, and other hosted harnesses
remain open. No new provider turn, deployment or hosted qualification
was run during merge preparation.

Prior source `57d3767eac` jobs 122590643944, 122590643983 and
122590644161 ended after runner shutdown/cancellation without final
Vitest results. The shutdown cause is unproven. No retry was issued
before this source was superseded by the required server recovery fix.
These attempts remain failures/incomplete evidence. Fresh exact-head CI,
legacy status, completed Greptile 5/5, resolved feedback and normal
merge eligibility remain required.

## Risks

Different-artifact A→B/B→A, the normal drain-free Cloud rollout path,
other hosted harnesses and the complete concurrency/viewer matrix remain
open. Frozen branch builds are development-build evidence. This PR owns
qualification and evidence; production defects must be fixed in their
earlier owning slice.

## Model Used

OpenAI GPT-6 through Codex, with reasoning, repository tools and code
execution. The runtime does not expose a more specific 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
- [ ] 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-27 21:58:09 -05:00
DottaandPaperclip d1f983e395 test(evals): distinguish team pricing from negated per-user charges
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-27 21:56:43 -05:00
DottaandPaperclip 9434442348 test(evals): reject waived required skills without confusing unrelated history
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-27 21:56:43 -05:00
DottaandPaperclip 96dcd15449 test(evals): reject modal contradictions of required plan features
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-27 21:56:43 -05:00
DottaandPaperclip 021c155682 test(evals): ground team requirements in actual skill identities
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-27 21:56:43 -05:00
DottaandPaperclip 913ffeec7c test(evals): accept substantive single-page plan paraphrases
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-27 21:56:43 -05:00
DottaandPaperclip 09ad9adce2 feat(server): adopt running remote agents through durable controller checkpoints (#17439)
## Thinking Path

> - Paperclip must keep admitted remote work alive while its main server
is replaced.
> - Runner owns recovery mechanics and exposes opaque checkpoints
through #17097.
> - The server owns company scope, encryption, Stop, tool authority and
execution ownership.
> - A successor must prove current ownership before it adopts the
original execution.
> - Checkpoint bursts must also leave capacity for normal requests and
lease renewal.
> - This PR persists and adopts that authority through the existing
runtime boundaries.

## Linked Issues or Issue Description

**What existing behavior does this improve?**

Remote agents retain the original execution during a bounded main-server
outage.

**Current behavior**

A server restart can lose the controller's local state and connection.
An unsafe replacement could repeat a turn or an uncertain mutation.
Checkpoint writes in the request pool can also delay ordinary requests
during an aligned burst.

**Proposed behavior**

Restore encrypted control records from Postgres and adopt the original
runner under a fenced lease. Recover known tool receipts through current
tool authority. Give control checkpoints a shared pool capped at two
connections per database owner.

Depends on #17097. Successors are #17455 and #17456. Qualification and
presentation remain separate review slices.

## What Changed

- Add company/run-bound encrypted checkpoint records and migration 0394.
Keep the SQL idempotent after renumbering against current master.
- Recover startup and expired ownership through native runtime and
heartbeat. Preserve the sandbox lease, admitted runner artifact, harness
configuration, native session and active turn.
- Keep Stop, finalization, preparation ownership and stale-writer
fencing transactional. Preserve graceful detach and natural crash
takeover.
- Recover committed tool receipts through the existing authority.
Reauthorize reads and hold uncertain mutations.
- Bound startup retention with the existing coordinator and preserve
zero idle scans.
- Share at most two checkpoint connections per database client. Keep
application and liveness capacity separate. Close the checkpoint pool
during shutdown; late writes cannot reopen it.
- Count SQL across both application and checkpoint clients. Prove
request/liveness progress, command recovery and failure after pool
shutdown with real Postgres.

## Verification

Project creation recovery now uses the existing project activity receipt
owner. It retains authenticated input normalization, fingerprint checks
and current run authority after the receipt lock. An absent receipt
returns no result before mutation. The new lost-HTTP-response and
no-effect regression uses real API routes and Postgres. The seven
transport cases pass locally. This Mac skips all 20 database cases. On
current source `5de803c2cd`, Linux [job
122593415890](https://github.com/paperclipai/paperclip/actions/runs/40620576702/job/122593415890)
executes all 20 project-tool cases successfully (9.480 seconds),
including the committed-project lost-response regression. Its shard
passes 1,627 cases with three unrelated skips. Server typecheck passes.
The transport regression initially has two failures; a subsequent
incorrect expectation about schema defaults was corrected before the
final pass. Ordinary execution adds no checkpoint writes or recurring
work.

Current candidate `5de803c2cd` includes the project-creation receipt
recovery fix and master `2cd747d1b6`. Migration 0394 retains the prior
idempotent checkpoint DDL. Every master SQL file and journal entry is
preserved. Snapshots 0390–0394, migration checks and server typecheck
pass.

The ordinary warm-turn regression fails on its second turn before
`a219ab51ad`. After correction, three completed warm turns select the
correct prior checkpoint and preserve the original session. All 288
provider-wiring cases pass. The control plane, external persistence
callback, identity rotation and filesystem are real; the backend and
database-load seam are scripted. The 13 warm admission/configuration
variants also pass after final master integration. This does not qualify
an underlying harness.

At current source `5de803c2cd`, Linux [job
122593415907](https://github.com/paperclipai/paperclip/actions/runs/40620576702/job/122593415907)
passes all 940 native-session-executor cases (61.431 seconds), including
the warm external-checkpoint behavior; the shard passes 2,358 cases with
one skip. Current [Runner job
122593415475](https://github.com/paperclipai/paperclip/actions/runs/40620576702/job/122593415475)
passes the native recovery lane: 115 passes and five container-only
skips, including the encrypted restore guard, fresh preparation (63.189
seconds), blocked claim lock (1.226 seconds) and recovery beyond 101
blocked owners (3.897 seconds). The first lane passes 2,215 cases with
one skip. The SQL cost test reports zero idle and streaming SQL for both
output volumes; this is component evidence, not a production capacity
claim. At prior candidate `1ff7bb44f4`, Linux job 122549307215 passes
all 938 native-executor cases, including the three-turn
external-checkpoint regression. Job 122549306469 passes the native
recovery lane with 115 passes and five container-only skips, including
the encrypted-restore session guard, fresh preparation (63.664 seconds),
claim-lock contention (3.961 seconds), and 101-owner recovery (3.824
seconds). This Mac skips the real-Postgres suite. The earlier full local
executor attempt has 921 passes and 16 failures during embedded-Postgres
initialization before assertions. The original fixture collisions and
their corrections remain recorded.

At earlier candidate `8fbe62b41d`, server shard job 122535673841 has
3,876 passes, one failure and one skip in an unchanged expiry-worker
retry/drain timing test. The same server/database tree on qualification
source `b64cac6951` passes all 20 expiry cases and all 3,877 shard
cases. The single diagnostic retry, job 122541891915, passes all 20
expiry cases and all 3,877 shard cases (one skip). No assertion was
weakened. The original failure remains recorded and its exact timing
race is not proven. All Actions checks and legacy status passed on
`8fbe62b41d`, with completed Greptile 5/5 and no open feedback. The next
candidate `1ff7bb44f4` also passed all Actions checks and Greptile 5/5.
Its Paperclip Review remained queued before the new master conflict
required integration. The new candidate needs fresh exact-head CI and
reviews; old checks do not qualify it. Migration generation is
checkpoint-only, all master SQL and journal entries remain unchanged,
and migration checks, server typecheck and all 13 warm-owner variants
pass after integration. The first migration check was blocked by TSX
sandbox IPC; its permitted repeat passes. The first warm-test command
used an incorrect path and ran no tests; the corrected command supplies
the 13-case receipt.

All 16 database pool-lifetime/options/teardown cases pass after granting
loopback permission; the first batch had two EPERM failures and 14
passes. Earlier semantic-tool/HTTP recovery, adoption, encryption-batch,
zero-streaming-write and idle-SQL receipts remain source-attributed in
the [qualification
record](https://github.com/paperclipai/paperclip/blob/2ff66f57da0da35bac1c19a2366ea4b84d87a986/doc/plans/2026-10-22-hot-upgrade-qualification.md).
That record retains earlier assertion, setup and cleanup failures and
their corrections. No failed gate is waived.

The historical 300-session component campaign passes four after phases:
steady read p99 is 107–108 ms at 500 reads/s and 100 writes/s;
aligned-burst read p99 is 103–105 ms after the bounded pool, versus
584–689 ms before. This comparison isolates the persistence corrections.
It does not measure the final stack's hosted active-agent capacity. The
hosted zero-agent API pair leaves SQL and CPU essentially unchanged, but
both arms fail absolute latency gates and candidate peak cgroup memory
fails its gate. The active-agent/viewer matrix, different-artifact
upgrade and rollback remain open.

Run `PAPERCLIP_TEST_DATABASE_URL=<owned-disposable-postgres> pnpm
--filter @paperclipai/server exec vitest run
src/services/native-runtime/native-runner-restart-recovery.integration.test.ts`.

Previous head `f2db8a6568` had one failed workspace setup gate: [job
122555672441](https://github.com/paperclipai/paperclip/actions/runs/40608984238/job/122555672441)
passes all 4,169 UI tests and 285 CLI cases (one skip), but the company
import/export suite reaches its 30-second health deadline during doctor
startup. Its output does not reach the server-start step. The CLI,
server, database, shared, adapter and plugin trees are identical on
qualification source `a866619d7b`, whose [job
122555886663](https://github.com/paperclipai/paperclip/actions/runs/40609057937/job/122555886663)
passes that fixture and all 286 CLI cases. The one diagnostic retry,
[job
122561057225](https://github.com/paperclipai/paperclip/actions/runs/40608984238/job/122561057225),
passes the formerly failing fixture and all 286 CLI cases. All Actions
checks and legacy status on `f2db8a6568` pass. Its exact-head Greptile
completed at 5/5 with no open feedback. The current integrated head
requires fresh checks and a completed Paperclip Review before merge. The
original failure remains recorded; its exact timing cause is unproven. A
repeated failure requires investigation and repair rather than another
retry.

All current-head CI, legacy status, exact-head completed Greptile 5/5,
resolved feedback and ordinary GitHub merge eligibility remain required
before merge.

The latest integration preserves master’s published Copilot v70 profiles
and every published migration. Checkpoint migration
`0394_conscious_whizzer.sql` was generated with `pnpm db:generate` and
retains the prior idempotent DDL. The Runner vendor rebuild and replay
parity checks pass. Server typecheck and all 13 warm-owner variants pass
after that rebuild. The imported report-lock patch is byte-identical to
master; its intentional patch-context whitespace is retained, and the
feature delta passes whitespace checks. No hosted experiment was run.

## Risks

The pool adds up to two active connections per instance, shared across
agents. Checkpoint delivery can wait behind that bound; it still
requires its commit. Steady component-test Postgres CPU rises by about
1.7 percentage points of a two-CPU allocation. These corrections do not
remove the stack's control and renewal writes. The migration and key
must survive replacement. Fresh-database tests and local load do not
establish different-artifact hosted upgrade or rollback continuity.

## Model Used

OpenAI GPT-6 through Codex, with reasoning, repository tools and code
execution. The runtime does not expose a more specific 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
- [ ] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [ ] All Paperclip CI gates are green
- [ ] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-10-27 21:39:23 -05:00
DottaandPaperclip 94a780286f fix(server): schedule tool health from committed changes and deadlines (#17554)
## Thinking Path

> - Paperclip manages AI-agent work and its connected tools.
> - Idle hosted instances need their database and network activity to
stop.
> - The maintenance tick queries tool connections even when no health
check is due.
> - Existing connection rows already contain eligibility and the last
health observation.
> - This pull request reconstructs health deadlines and refreshes them
after committed changes.
> - The shared coordinator preserves retries, drain, and shutdown
without another private timer.

## Linked Issues or Issue Description

**What happened?**

The aggregate maintenance tick scans connection health every 30 seconds.
Empty instances and connections with fresh health observations still
cause SQL activity.

**Expected behavior**

No eligible connection means no recurring health SQL. Eligible
connections retain the existing 15-minute proactive check. Configuration
changes and health observations update the schedule after commit.

**Steps to reproduce**

Start a server with heartbeat scheduling enabled and no tool
connections. Let startup finish and observe two maintenance ticks. The
old code repeats the health inventory query. The new startup regression
verifies that those ticks do not invoke the health inventory.

**Paperclip version or commit**

This branch includes merged parent #17518 and master
`96727b3cfefb61f85ffe1fbc29a9b6dd6837efe8`. The 47 changed paths belong
to the single tool-connection health duty. No database file differs from
master.

Related: #14638 covers runtime-auth exclusions. #15448, #15325, and
#11910 concern MCP failure classification. This PR preserves those
provider policies and does not replace their work.

## What Changed

- Keep the GitHub error-projection unit fixture at the health-write
boundary and verify the real transaction path in the PostgreSQL
health-worker suite.

- Add a health schedule owned by tool access. Read lean eligibility
fields and saved observation timestamps.
- Register health work with the existing coordinator. Refresh only dirty
connection/application/company scopes using bounded inventory pages,
check due connections in fair company batches, continue concrete due
backlog after one second, and retain failures with backoff.
- Notify before supported eligibility and observation writes in their
owning transactions. Cover API/gallery setup, OAuth, catalog/gateway
observations, email, voice, access removal, deletion, and settings.
- Commit connection creation with grant, binding, and runtime-slot SQL
before its wake. Keep provider calls outside the new transactions.
- Keep provider-to-transport mapping in the chat catalog. SDK-only chat
changes do not wake health work.
- Replace aggregate health scans, retain the public manual sweep, and
document the producer audit and remaining sleep limits.
- Keep metadata-only example and Smoke Lab installs scoped. Lock and
re-read application type before publishing a real eligibility change.
- Keep failed inventory reads on their own retry deadline while healthy
due batches continue.
- Apply fixture migrations before using external disposable databases in
all six producer suites.

## Verification

Published head: `8c1d293d1ae2b7db753ab20f5a2a2edec1fb0a62`. Fresh CI and
reviews are required for this exact head.

- **623 distinct targeted cases pass.** The final four complete health,
fair-batching, GitHub health recovery, and startup suites pass 80 cases
after the retry fix. Five complete producer suites pass 543 cases: tool
access 469, access 18, email 45, GitHub events four, and Smoke Lab
seven. The earlier 26 health cases are part of this total, not
additional cases.
- The six producer suites first passed against separate, initially empty
PostgreSQL 17 databases at `acbf262843`. They apply their own
migrations. The subsequent repair changes only the health worker and its
regression; its complete final consumer suites pass on that integrated
parent. Server typecheck and build pass with the final repair.
- **Installer amplification:** five real installs with 205 unrelated
connections reproduced 1,035 example rows and 1,045 Smoke Lab rows.
Repeated metadata installs now load only changed fixture connections.
The same cases restore an excluded application through each installer
and require all 205 unrelated IDs to re-enter the schedule.
- **Concurrent eligibility:** a real PostgreSQL lock-wait case requires
the installer to notify after a concurrent type change. A mutation that
retains the lock but uses the old lookup fails the settled-hint
assertion; original source was restored byte for byte.
- **Retry isolation:** the failing baseline read one unavailable company
three times while another company's 60 due checks drained. Final tests
require one initial read, at least 30 seconds between failed reads,
prompt healthy progress, eventual recovery, and SQL quiet after
settlement.
- Real-service producer coverage includes AgentMail activation/pause,
GitHub installation changes, and member access removal. Lifecycle
coverage includes outer commit/rollback, startup reconstruction,
drain/resume, failure, and shutdown.
- Failure history and exact evidence scope: [health
acceptance](https://github.com/paperclipai/paperclip/blob/8c1d293d1ae2b7db753ab20f5a2a2edec1fb0a62/doc/idle-tool-connection-health.md#acceptance-follow-up-after-the-plugin-parent-merged-october-27),
[producer
audit](https://github.com/paperclipai/paperclip/blob/8c1d293d1ae2b7db753ab20f5a2a2edec1fb0a62/doc/plans/2026-10-24-tool-connection-health-sleep-audit.md).
Prior remote failures and earlier 706-case evidence remain historical.
Startup tests emitted listener-count warnings; all assertions passed. No
full local repository-suite, deployed sleep, fleet savings, or live
provider qualification claim is made.

## Risks

- Supported live writers must use the transaction signals. Independent
SQL writers and other replicas need their own wake integration.
- Configured eligible connections still have a real proactive health
obligation. This does not prove Cloud alarm coverage or host/database
suspension.
- Existing manual probes and catalog operations can overlap. This
migration does not introduce a credential-version CAS or change provider
failure policy.
- Voice remains eligible under the previous health policy. Its generic
probe can still report an unsupported transport; changing that behavior
is separate work.
- No database migration, new table, workflow, or lockfile change. This
PR includes its merged parent and current inspected master; later stack
PRs and all current-head acceptance gates remain separate.

## Model Used

OpenAI Codex, GPT-6 family, with repository tools, code execution, and
reasoning. The exact serving version 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
- [ ] 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-27 21:37:50 -05:00
github-actions[bot]andlockfile-bot 5cfa2bf26d chore(lockfile): refresh pnpm-lock.yaml (#17811)
Refresh the CI-owned pnpm lockfile from current workspace manifests and patches.

Frozen install and 64 focused Product Journey tests passed locally. Full hosted CI passed on the exact generated head. Earlier browser failures remain documented in the PR.

Co-Authored-By: lockfile-bot <lockfile-bot@users.noreply.github.com>
2026-10-27 21:31:22 -05:00
DottaandPaperclip 33f99c6c5a docs(evals): preserve the composed operating section heading
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-27 21:18:36 -05:00