Commit Graph
7726 Commits
Author SHA1 Message Date
Dotta a477b2c5d8 fix(evals): preserve original task and inbox observation budgets 2026-10-28 08:17:14 -05:00
Dotta efa3382b21 test(e2e): fingerprint executed plugin CLI source and loader 2026-10-28 08:15:28 -05:00
Dotta 250ba62791 test(e2e): bind installed team to selected OpenCode runtime 2026-10-28 08:15:27 -05:00
DottaandPaperclip 1c6021a4e6 fix(evals): bind inline secret helper to actual consumer task
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-28 08:15:27 -05:00
DottaandPaperclip 0e4ebca61c fix(evals): bind approval wait to actual task workspace
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-28 08:15:27 -05:00
DottaandPaperclip dea44755b0 fix(evals): prepare prerequisite people through public membership routes
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-28 08:15:26 -05:00
Dotta 81987af644 Accept lifecycle-ready running workers in catalog readiness 2026-10-28 08:15:26 -05:00
DottaandPaperclip 8279c99008 fix(evals): clarify report details and link tested applications (#18009)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Product E2E reports help operators inspect real application
journeys.
> - A worker environment does not identify the application that a
journey tested.
> - Reports hid that URL and gave missing diagnostics too much space.
> - Standalone reports also sent the logo link to a missing parent page.
> - This pull request shows the recorded target and checks in the shared
report.
> - The benefit is a clear report with useful links and inspectable
diagnostics.

## Linked Issues or Issue Description

**What happened?**

A standalone Product E2E report had no application link in test details
or the screenshot gallery. Its details showed several empty diagnostic
sections before useful information. The logo could resolve to the page
host root and return 404. Campaign notes added outside the report shell
could overlap the fixed sidebar.

**Expected behavior**

Show the recorded application URL beside each test and screenshot. Put
recorded checks before optional diagnostics. Keep campaign context
inside the shared layout. Link the logo to the evaluations directory.

**Steps to reproduce**

1. Render a retained campaign at a standalone page path without a
history index.
2. Open a test with screenshot evidence and missing startup timing.
3. Inspect test details and gallery information, then click the report
logo.

**Paperclip version or commit**

Reproduced in the report renderer at `39e811c9c5`. This branch applies
the fix to current master.

**Deployment mode**

Static Product E2E HTML report generated from retained normalized
results.

## What Changed

- Add optional recorded `targetUrl` metadata and resolve existing
Product E2E and provider-connection targets. Only HTTP and HTTPS links
without embedded credentials are shown.
- Show the target URL in test details and screenshot gallery
information.
- Put recorded checks and execution facts first. Keep raw usage, timing,
and startup details under Diagnostics. Preserve missing metadata as
unknown.
- Keep campaign titles, descriptions, notes, and evidence links inside
the shared report layout during retained-evidence regeneration.
- Fix standalone navigation and let the brand lockup wrap at narrow
sidebar widths.
- Match report profiles by suite and recorded provider/model before
falling back to an inferred profile.
- Add report regressions and document the retained metadata contract.

## Verification

- Focused report tests: 86 passed across 8 files on the isolated branch.
Command: `node node_modules/vitest/vitest.mjs run --config
tests/runner-e2e/vitest.config.ts report-target.test.ts
report-navigation.test.ts report-catalog.test.ts
first-task-report.test.ts report.test.ts dashboard-regenerate.test.ts`.
- Browser verification covered dark desktop widths 1440 and 1000, light
intermediate width 780, and dark mobile width 390. It covered the
drawer, URL links, gallery keyboard navigation, focus return, and the
logo destination.
- The published retained report keeps all 3 original passing cases and 7
recorded checks. Its campaign and screenshot bytes remain unchanged.
This presentation refresh made zero provider calls.
- Full `pnpm build`, `pnpm -r typecheck`, and the eval TypeScript check
passed after rebuilding the reused package dependencies. The first
typecheck attempt had stale local dependency builds; those errors are
resolved.
- The local `pnpm test:run` attempt hit repeated embedded PostgreSQL
bootstrap failures in server suites. I stopped that attempt and retained
its log. It is not counted as a passing check. Current-head CI remains
the full test gate.
- Review follow-ups add provider/model and cross-suite profile
regressions. Malformed campaign presentation metadata is rejected before
any report or retained-result writes; ten malformed input cases verify
that retained results stay unchanged.

## Risks

- This changes presentation across Product E2E reports. Historical
reports without a target show “Not recorded” rather than an inferred
URL.
- Unknown startup reuse data remains in raw metadata but no longer
creates an empty table.
- Standalone logo links open the shared public evaluations directory.
Campaign history links still use a matching history index when present.
- No application runtime, database, or measurement verdict changes are
included. Private QA configuration and raw campaign evidence stay
outside this PR.

## Model Used

- OpenAI Codex, GPT-6 family, with reasoning, code execution, and
browser tools. The exact backend model ID and context-window size are
not exposed in this session.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [ ] 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 13:00:54 +00:00
DottaandPaperclip 3bd0d81c7b fix(e2e): follow proven workspace deferrals during onboarding (#18008)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Product E2E journeys verify the user outcome through the browser and
scoped APIs.
> - An onboarding child can wait while its parent owns their shared
workspace.
> - The server records that no provider work started and schedules a
durable replacement.
> - The journey rejected that expected wait, and feedback counted it as
unknown legacy execution.
> - This pull request follows the exact replacement and records the
distinct no-provider evidence.
> - The child must still finish through native execution and produce the
independently checked download.

## Linked Issues or Issue Description

Refs #17940.

**What happened?**

The fresh-workspace journey failed with `onboarding_first_task_failed`
when a child encountered shared-workspace contention. The cancelled
admission had an explicit `workspace_wait` receipt with
`providerWorkStarted: false`. Its linked replacement was still
scheduled. The runtime had not been selected. The default `legacy` value
did not represent a provider execution.

**Expected behavior**

Keep both rows and their run-limit cost. Follow only the unique
replacement for the same company, agent, and issue. A pending
replacement must not pass. Real failures and contradictory execution
evidence must still fail.

**Steps to reproduce**

1. Start a native onboarding parent and accept its child-task proposal.
2. Observe the child admission while the parent still holds their
workspace.
3. Present the server's no-provider cancellation and its durable
scheduled replacement to the journey and feedback collectors.

## What Changed

- Add a shared predicate for the explicit no-provider workspace-deferral
receipt. Reject runtime, process, output, usage, and cost evidence that
contradicts it.
- Follow exact, unique retry lineage during onboarding. Wait for active
or scheduled replacements without repeating browser actions. Preserve
the campaign deadline, run cap, native artifact attribution, and
download oracle.
- Retain per-run feedback inspection classifications: `native_events`,
`provider_not_started`, or `incomplete`. Require exhaustive event reads.
Keep pending work and uncertain execution partial.
- Add causal regressions and document the evidence contract. Historical
failed attempts keep their original grades.

## Verification

- Red: the new journey regression failed with the observed
`onboarding_first_task_failed` before the repair. The new feedback cases
also failed before the repair.
- Green: 70 journey tests and 74 feedback-family tests passed. The final
affected journey/feedback gate passed 275 tests plus 137 Node checks.
Five retry-lane reset cases failed before the review correction and
passed after it.
- `pnpm test:e2e:runner:typecheck` passed after the retry-counter
correction.
- `pnpm -r typecheck` and `pnpm build` passed before the final rebase.
- The full local `pnpm test:run` and harness unit gate encountered
embedded PostgreSQL startup failures. The harness gate passed 4,574
tests and failed its database-startup test. The final focused
journey/feedback gate and all 137 Node checks passed. CI will provide
independent full-suite results before merge.
- Current-head CI passed 55 checks; two checks skipped and one was
neutral. Greptile is 5/5, with zero unresolved review threads.
- Live Cloud verification will use the reviewed harness and Operations
revisions. This PR does not claim that a fresh Cloud campaign has
passed.

## Risks

A broad cancellation exemption could hide real failures. The exemption
requires the server's explicit receipt, unresolved runtime selection, no
contradictory execution evidence, and exact durable lineage. Missing
successors remain pending until the existing deadline. A successful
native child and valid downloaded bytes remain required. No server
behavior, approval policy, or budget policy changes.

## Model Used

OpenAI Codex, `gpt-6.1-sol`, with reasoning, source inspection, tool
use, and code execution. The host does not expose its configured
context-window size.

## Checklist

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

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-10-28 07:58:41 -05:00
DottaandPaperclip e7ea2e2961 fix(evals): export grades for expanded qualification batches (#18010)
## Thinking Path

> - Paperclip manages AI agents and their work.
> - Product E2E campaigns retain each attempt and its independent
grades.
> - Braintrust receives product and cleanup grades for each retained
attempt.
> - A six-case qualification produces twelve scores. The export allowed
only eight.
> - Experiment creation succeeded, but grade insertion stopped before
dispatch.
> - This fix allows fourteen scores so the six- and seven-case batches
retain every result.
> - Operators can inspect failed and successful grades without running
an agent again.

## Linked Issues or Issue Description

Refs: #17044

**What happened?**

A retained six-case Product E2E campaign created its Braintrust
experiment, then failed with `Experiment ingestion allowance exhausted`.
Its twelve deterministic scores exceeded the eight-score cap. No insert
request was sent. Agent results and model accounting remained saved.

**Expected behavior**

The bounded qualification batches must export both grades for every
selected attempt. Failed grades must remain visible.

**Steps to reproduce**

Create an experiment through `openExperimentIngestion`. Insert six or
seven events with `product_pass` and `cleanup_pass` scores. The old
limit rejects the insert before it reaches the transport.

**Paperclip version or commit**

Reproduced on master `cff331f6ca0a652b5e41641c68dfa5fa584c22ae`.

**Deployment mode**

Local Docker controller built from source. The failure is in the shared
Product export path.

## What Changed

- Raise the finite experiment score cap from eight to fourteen. Keep the
three-request, 4 MiB and 60-second limits.
- Add regressions for the six- and seven-case batches. Keep the failed
product grade in each test batch.
- Verify that the receipt collector accepts the old eight-score policy
and the new fourteen-score policy. It rejects a fifteen-score policy.
- Document the seven-attempt export ceiling. This change does not add
agent calls or automatic retries.

## Verification

- Before the fix: both new batch regressions failed with `Experiment
ingestion allowance exhausted`.
- After the fix: 67 tests pass across experiment ingestion, ingestion
accounting, experiment projection and scheduled finalization.
- Command: `node node_modules/vitest/vitest.mjs run --config
tests/runner-e2e/vitest.config.ts
tests/runner-e2e/experiment-ingestion.test.ts
tests/runner-e2e/ingestion-usage.test.ts
tests/runner-e2e/scheduled-finalization.test.ts
tests/runner-e2e/braintrust-experiment.test.ts --configLoader runner
--cache=false`.
- `git diff --check` passes. All 58 current-head checks are acceptable,
including typecheck, build and tests. Both reviews are 5/5, with no
unresolved threads.
- Live agent attempts will not be repeated to verify this reporting fix.
Recovery uses the saved results and a separate bounded ingestion
receipt.

## Risks

- New exports can submit at most six more deterministic scores per
experiment. These are saved grades, not model judge calls.
- Larger campaigns still fail closed. Existing receipt files keep their
original policies and traffic counts.
- This fix does not resolve the plan-lifecycle behavior failures
observed in the qualification.

## Model Used

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

## Checklist

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

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-10-28 07:50:59 -05:00
DottaandPaperclip e93732c3d4 fix(server): deliver voice replies from commits and saved deadlines (#17578)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Phone calls receive approved answers from the existing chat
publication queue.
> - The chat maintenance timer checks for voice replies every second,
including when no reply is ready.
> - A reply can be saved before its publication commits. An early wake
alone can miss that final transition.
> - Existing session, reply, publication, and action rows already record
delivery and recovery work.
> - This pull request uses committed changes and saved deadlines to
drive phone reply delivery.
> - Empty reply queues become quiet while authorization, ordering, and
uncertain-send protection remain in place.

## Linked Issues or Issue Description

Stacked on #17576. Related delivery infrastructure: #15625. Related
voice connection work: #11418.

**What existing behavior does this improve?**

Background phone reply delivery and recovery of abandoned dispatch
intents.

**Current behavior**

Chat maintenance calls voice reply delivery every second. It also scans
old dispatch intents. Publication transport starts a direct push before
the final publication commit. The timer masks that timing gap.

**Proposed behavior**

Committed publication, reply, session, and configuration changes wake
the shared coordinator. Ready replies drain in bounded passes. Saved
rate-limit and dispatch-expiry deadlines retain recovery. An empty queue
or a permanent delivery barrier has no recurring reply scan.

**Reason and benefit**

Remove recurring SQL from idle phone reply delivery without dropping
replies, replaying uncertain sends, or adding a queue table.

**Breaking changes**

No API or schema change. Explicit manual recovery remains available.
Inbound admission cleanup, history retention, and reports remain on
their current paths for separate migrations.

## What Changed

- Extract ordered reply state and multipart policy within the voice
owner. Retain current authorization and atomic dispatch claims.
- Register a scoped reply worker with startup reconstruction, fair work
batches, failure backoff, drain/resume handling and shutdown ownership.
- Extend the existing shared dispatcher with normalized partial-page
results to preserve the bounded parent recovery contract. Existing
complete-array consumers retain their calls.
- Signal before relevant writes in their existing transactions. Both
normal publication completion and operator resolution wake the actual
conversation after commit.
- Bound reply inventory to 100 total headers per refresh. Preserve
partial scans, concurrent changes and newer denied-call restoration
obligations across reconstruction.
- Track abandoned dispatch actions independently of live calls.
Quarantine expired intents without resending them.
- Use existing active-call authorization checks to reactivate replies
that were previously denied. Healthy call inspections do not rescan
empty reply queues.
- Remove the periodic reply scan and the early direct publication push.
Keep provider requests outside database transactions.

## Verification

Published head: `1435cab10be3f95c38ab6672d2a890ae49e9d300`. Voice
recovery #17576 has landed at master
`e1ba77f06771a27114b3999004b0ca5e3c172dd4`. A normal merge reconciles
squash ancestry while preserving the complete reviewed 31-file reply
patch byte for byte and all unrelated master changes. The PR now targets
master; fresh exact-head CI and Greptile are required. The prior
449-case/typecheck/build results below cover the identical owned source,
not a new full-suite run.

- **449 distinct targeted cases pass**: 111 complete voice-store/reply;
19 complete parent recovery; and 319 complete tool-gateway,
secret-proposal, shared dispatcher/coordinator/batching/startup/hostname
cases. Production server typecheck and build pass. The policy checker
and its Node tests pass. Later edits record evidence only.
- Two real normal-publication/operator-resolution tests seed 105
unrelated calls and 105 future dispatches. Five publications selected
**1,065/1,060 inventory rows before repair**; both paths now pass the
same **125-row total budget** and deliver every answer once. This counts
selected SQL results, not physical tuple visits or host savings.
- Publication commits now signal their actual conversation. The voice
reader returns at most 100 total session/action headers per refresh,
preserves phase/cursor state and retries, and resets on worker
registration. Current-state checks and dispatch claims still own
provider effects. The 105-action case measures the page cap, restarts
the same owner during reconstruction, waits at saved future deadlines
and quarantines every abandoned action without resending.
- A real 403 fixture proves that an older broad scan cannot erase a
denied call first observed behind its cursor. Its owner callback still
emits the committed restoration wake after scan completion. The existing
actual-service authority-restoration and final-publication timing tests
remain in the full suite. They are not replaced by direct helper calls.
- Guarded removal of conversation scoping, cursor reset or the denial
revision fence fails the intended budget, 100-versus-5 restart or
missing committed-wake assertion; source is restored. An initial
shadowed fixture name and an inadequate due-action reset probe are
retained as failed attempts in the [current
audit](https://github.com/paperclipai/paperclip/blob/d2c0a7de8c3e9cac8382b1268f3f5d883a2067b3/doc/plans/2026-10-25-voice-reply-delivery-sleep-audit.md#publication-inventory-and-paging-acceptance-october-28).
- Parent recovery still passes paging, restart, behind-cursor insertion,
feature changes, actual disablement, quiet health observations, current
authority, exact-scope failure fences and wildcard-failure isolation
through the shared worker. Four existing array-based worker consumers
retain their API and pass their full suites.
- The two voice fixtures self-migrate separate empty databases. Legacy
tool-review/secrets suites use separate migrated clones. Earlier
full-local attempts remain limited by embedded PostgreSQL setup and are
not passing full-matrix claims. Older counts apply only to their stated
revisions. Fresh exact-head Greptile, Ponytail if present, security and
all CI remain merge gates. No live-provider, multi-writer,
external-wake, deployed-sleep or savings claim is made.

## Risks

- Missing a supported producer can strand work. Tests cover real
enqueue, retrieval, normal publication, and operator publication paths.
Startup reconstructs existing records.
- Signals cover the process-local database owner. Independent SQL
writers or other replicas need their own wake contract.
- Authority restoration relies on the existing live-call recovery check.
This dependency must be preserved if that owner changes later.
- A provider acceptance receipt does not prove speech. Unknown outcomes
remain blocked from automatic resend.
- This change does not extend Cloud alarms, allow sleep during live
calls, or prove deployed suspension or cost savings.

## Model Used

OpenAI GPT-6 via Codex, with repository inspection, reasoning, code
execution and test tools. The runtime does not expose a more specific
deployment identifier or context-window size.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used with the available version and
capability details
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have described the issue in-PR following the relevant issue
template
- [x] I have not referenced internal or instance-local Paperclip issues
or links
- [x] My branch name describes the change and contains no internal
ticket identifier
- [x] I have run the selected 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 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:50:27 -05:00
DottaandPaperclip e1ba77f067 fix(server): schedule live voice recovery from session changes and deadlines (#17576)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Voice calls retain durable session state and provider identities.
> - The chat maintenance timer scans live voice sessions even when no
call exists.
> - Session writes, saved expiry and active-call inspection deadlines
identify real work.
> - This pull request moves live-session recovery to the shared
coordinator.
> - Idle session recovery becomes quiet without losing exact-call
cleanup or current authorization checks.

## Linked Issues or Issue Description

Refs #17572. This PR is stacked on receiver discovery. It owns only live
voice session recovery. Reply delivery, inbound admission cleanup,
inbound history retention and call reports remain separate migration
slices.

**What happened?**
The one-second chat maintenance lane reads voice settings and scans live
sessions even when an instance has no calls or only terminal history.

**What did you expect?**
Reconstruct live calls on startup. Wake on committed session or
configuration changes. Inspect active calls and retry cleanup at actual
deadlines. Stop querying when no live obligation remains.

**Steps to reproduce**
Start an instance with no live voice sessions. Let startup settle. The
old maintenance method continues to read settings and session inventory
every chat maintenance pass.

## What Changed

- Add a voice-owned bounded deadline reader and scoped worker on the
existing coordinator. Retain concurrent writes across pages and reset
partial scans on restart. No tables or migrations are added.
- Separate generic connection health observations from configuration
changes. Existing receiver and command consumers retain their
notifications. Voice eligibility and provider operations remain in the
voice owner.
- Signal existing session transactions and configuration/feature
changes. Keep provider calls outside database transactions. Standalone
session writes use one small transaction helper.
- Preserve saved expiry, the two-minute unknown-creation grace,
active-call authorization and missed-hangup inspection, and
exact-provider cleanup. Recovery never creates a provider call.
- Retry transient authority lookup failures instead of treating them as
confirmed revocation.
- Fence expiration against a provider identity bound after discovery. A
late known call remains eligible for cleanup.
- Preserve work through rollback, drain, restart, concurrent refresh,
backoff and shutdown. Page inventory and rotate bounded batches across
companies.
- Leave the four other voice maintenance duties in the periodic lane.
- Document producer coverage and the supported writer contract in
`doc/idle-voice-session-recovery.md` and the dated audit.

## Verification

Published head: `f0b2e3cc22a18e7d08b10d4fc02aae4a19a52f30`. Receiver
#17572 has landed in master at
`dce004259394486f6361d0c0dd5a33a5272acc0a`. This normal merge reconciles
squash ancestry; the complete 22-file voice recovery patch is
byte-for-byte identical to the reviewed and tested `ad79c7e805` patch,
while all unrelated master changes are preserved. The PR now targets
master. Fresh exact-head CI and Greptile are running; interrupted
Ponytail turns are not completed verdicts under the maintainer’s
clarified merge policy, and an actual failing verdict still blocks.

- **210 distinct targeted cases pass on the current repair**: 19
complete recovery lifecycle cases and 191 complete voice-store,
coordinator, batching, startup and hostname cases. Production server
typecheck and build pass. Later edits record evidence only.
- CI `40633667141` on prior head `1b6323c164` failed the feature-change
assertion with `34050 < 25000`; its verification aggregate also failed.
The test now disables automatically advancing fake time, drives 20
controlled scheduler turns and requires all 205 calls to close before an
unrelated inspection deadline can mask a lost wake. Removing generation
replay fails with missing closures. The repair does not benchmark
database/host speed or raise the elapsed-time bound.
- A real committed exact-call regression reproduces wildcard-backoff
starvation. The worker keeps the broad retry but processes independent
exact hints and cached due calls. Each check reloads current state and
authority. Failed exact scopes remain fenced. Removing wildcard
isolation fails the intended assertion; a successful broad retry then
leaves the worker SQL-quiet. Full-row and lean queries now share the
state/scope/cursor predicate.
- Earlier acceptance on `712f3862b5` passed 725 distinct targeted cases.
Its measurements remain useful history: five real metadata writes and
one health check over 205 future calls selected 1,230 rows before the
inventory repair and zero afterward, without changing the saved
deadline. Those older test counts are not added to the current 210-case
count.
- Both external voice fixtures self-migrate; the current full
voice-store run uses a separate initially empty database. Earlier
fixture/method/observer failures, source mutations and partial edit
attempts remain in the [current
audit](https://github.com/paperclipai/paperclip/blob/ad79c7e805367fc7e2df3ea53c942ca6c7d27365/doc/plans/2026-10-25-voice-maintenance-sleep-audit.md#wildcard-failure-and-deterministic-generation-acceptance-october-28).
Source is restored after guarded mutations.
- Older CI `40632057899` failed because its trusted policy script was
absent from the checkout, while build separately received a runner
shutdown signal. E2E shards succeeded but their aggregate failed on
policy. The current checkout includes the landed policy tooling and its
checker/tests pass locally. The shutdown cause is unproven; neither old
failed run is counted as passing. Earlier full-local attempts stopped on
embedded PostgreSQL setup failures and did not pass.
- Fresh exact-head Greptile, security and all CI must pass before merge.
A completed failing Ponytail verdict blocks; an interrupted turn without
a verdict does not. No full current local repository matrix, live
provider acceptance, multi-writer support, Cloud wake, host suspension
or savings is claimed.

## Risks

- Process-local hints cover the existing active writer and shared
clients. Independent SQL writers or another replica need explicit wake
integration.
- Membership, task binding, phone preferences and other authority inputs
remain checked on the existing 30-second active-call inspection deadline
and on use. This is not an instant cleanup guarantee for every authority
mutation.
- Unknown creation retains its existing maximum-duration grace. Cleanup
failures retain retries. A provider request is never replayed merely
because its creation response is unknown.
- Genuine configuration changes retain bounded reconstruction. Metadata
writes can probe parent eligibility, while health-only observations
leave voice recovery quiet. Paging state is process-local and
reconstructs from durable rows after restart.
- Active calls, the other voice maintenance owners and connector
transports remain real obligations. This does not expand Cloud alarm
coverage, relax sleep eligibility or prove deployed suspension.
- The receiver and Discord parents have landed. Current-master
compatibility and exact-head CI and Greptile remain merge gates.

## Model Used

OpenAI GPT-6 via Codex, with repository inspection, reasoning, code
execution and test tools. The runtime does not expose a more specific
deployment identifier or context-window size.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either 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:38:48 -05:00
Dotta 8cd9e8bc6b fix(evals): keep fast response initial observation on original clock 2026-10-28 07:26:09 -05:00
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