mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-10-06 10:48:12 +02:00
## Thinking Path > - Paperclip manages AI agents and their work. > - Its attention feed shows failed runs whose retry budget is exhausted. > - Startup retention builds this feed before startup completes. > - The feed joins every exhaustion event to the full run context, then removes duplicate runs in JavaScript. > - Recovery can revisit an exhausted run and append the same event again. This multiplies the data loaded into memory. > - This pull request selects one small row per run in PostgreSQL and makes exhaustion writes idempotent. > - Existing duplicate events can stay in the database without multiplying run contexts in server memory. ## Linked Issues or Issue Description Refs #13367. This fixes the repeated-event allocation path in the retention feed. Other full-feed sources and sweep cadence remain separate concerns. **What happened?** The attention query loaded one full run context for every matching exhaustion event. Deduplication ran only after the driver had loaded those rows. A run with thousands of exhaustion events therefore produced thousands of context copies. The startup retention sweep can exhaust the server heap while reading this result. **Expected behavior** The query should return one row per exhausted run and only the context fields that the feed needs. Repeated checks of the same exhausted retry budget should reuse the original event. **Steps to reproduce** 1. Create a failed run with a 32 KB context and 2,500 matching exhaustion events. 2. Build the attention feed, including dismissed items, as startup retention does. 3. Inspect the database result before JavaScript feed processing. The old join returns 2,500 copies of the run context. 4. Call bounded retry scheduling repeatedly for a run at its retry limit. The old writer appends another exhaustion event on every call. **Paperclip version or commit** The attention query was introduced by #9380 and is present in stable `v2026.831.1`. The retention caller is also present in that stable release. The later recovery callback added by #13075 provides a repeated path into the exhausted-budget writer. This change is based on `c0fda8fac` after rebasing onto current master. Related PR: [#12162](https://github.com/paperclipai/paperclip/pull/12162) changes retention cadence and newer-run suppression queries. This change addresses the exhaustion-event join and duplicate event writes. ## What Changed - Select the newest company-scoped exhaustion event per run with a PostgreSQL `DISTINCT ON` subquery before joining run data. - Project only `issueId` and `taskId` from run context. Preserve JSON types, fallback behavior, run ordering, company filters, and run/agent status filters. - Reuse an exhaustion event for the same run, reason, attempt, and retry limit under the existing run-row lock. Recognize historical events without a migration. - Skip sequence allocation and live publication when a receipt already exists. - Document the run-log behavior and add PostgreSQL regression tests. ## Verification - Focused attention, retry-scheduling, and event-sequencing suites: 72 tests pass on the rebased head `39ce77158`. - The large-history fixture verifies two database result rows under 4 KB, newest-message selection, task-ID fallback, and company/status filtering. This assertion runs before feed deduplication. - Concurrent event tests verify one receipt across two database clients, reuse of historical receipts, distinct reason/attempt/budget keys, and stable event sequences. - Repeated scheduling through a new service instance produces no extra run-log or live events. - `pnpm --filter @paperclipai/server exec tsc --noEmit`: passes. - `pnpm -r typecheck` and `pnpm build`: pass on the rebased head, including native runner checks. - Greptile: 5/5 on `39ce77158`, with no review threads. - [GitHub CI](https://github.com/paperclipai/paperclip/actions/runs/34929002304): all 25 workflow jobs pass, including all server/workspace test shards, serialized server suites, browser tests, typecheck, build, native-runner verification, and the release dry run. Security checks also pass. The branch has no merge conflicts. - `pnpm test:run`: stopped with unrelated failures. Two chat integration cases passed when rerun separately (2 passed, 993 unselected). Three skill-cache cases failed on both this branch and the unmodified parent commit, with `EACCES` during directory rename. The full suite is not reported as green. ## Risks - No schema migration or data cleanup is required. The query still scans matching event history in PostgreSQL; its result size now scales with exhausted runs. - This does not bound every source in the attention feed or change retention scheduling. - An exhaustion receipt is emitted once per retry decision. Consumers that observed repeated copies will now receive one event. - Native source-event replay handling stays on its existing path. - A deployed application boot has not been verified. ## Model Used OpenAI GPT-6, used through Codex with reasoning, repository inspection, code editing, and test execution. The runtime does not expose a more specific model snapshot 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 the focused tests locally and they pass (full-suite limitations are documented above) - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge Co-authored-by: Paperclip <noreply@paperclip.ing>