mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-10-14 08:26:46 +02:00
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - The heartbeat service schedules and runs agent work. > - Previous refactors moved queue admission, recovery, and run control into separate modules. > - Timer ticks, issue monitors, and session-goal recovery still occupy more than 1,100 lines in the main service. > - This pull request moves that scheduling code into one module with explicit dependencies. > - This makes scheduling easier to review and test before we split the execution pipeline. ## Linked Issues or Issue Description Refs #15685, the merged run-control extraction. A search found no duplicate open scheduling extraction. **What existing behavior does this improve?** Maintenance and testing of heartbeat scheduling. **Current behavior** The main heartbeat service contains 10,473 lines. Scheduling shares a file with the execution pipeline. **Proposed behavior** Move scheduling into `server/src/services/heartbeat/scheduling.ts`. Keep the same public methods, admission rules, database claims, and execution behavior. The main file falls to 9,330 lines. **Reason and benefit** Give timer ticks, issue-monitor recovery, and session-goal recovery one clear module boundary. **Breaking changes** None intended. Existing heartbeat exports and method signatures remain available. ## What Changed - Add `createHeartbeatScheduling` with 11 explicit dependencies. Construction does not query the database or start timers. - Move timer ticks, issue-monitor dispatch and recovery, and session-goal recovery into the new module. - Keep queue admission, heartbeat policy parsing, and atomic timer claims in `queue.ts`. - Share the unchanged goal-control parser and issue-link formatter with their existing callers. - Add 20 focused tests. Document the module boundary in `doc/DEVELOPING.md`. ## Verification - 122 tests pass across 11 files: 20 new scheduler tests, 52 existing scheduling integration tests, and 50 adjacent queue, goal, native-selection, and task-drain tests. - New database tests cover cross-instance monitor claims, replacement schedules, deferred and failed admission, native ownership, archived companies, timer claim loss, worktree cutoffs, agent eligibility, goal recovery keys, pending-action deduplication, and invalid-action persistence. - AST comparison confirms 20 unchanged function bodies, unchanged remaining service statements, unchanged `executeRun`, and all 140 public exports preserved. - Workspace typecheck (`pnpm -r typecheck`) and build (`pnpm build`) pass. Greptile is 5/5 on commit `89a1a3b3aa428949eba349af5c1618391f97a19c`. All CI checks pass on that commit. The full test suite runs in CI; local verification was targeted. - The first CI attempt hit a 15-second timeout in the first test of unchanged `plugin-scoped-api-routes.test.ts`. All nine tests pass locally in 6.6 seconds. That shard passed on its one retry without code changes. - Run the new tests with `pnpm exec vitest run server/src/services/heartbeat/scheduling.test.ts --maxWorkers=1`. ## Risks - Incorrect wiring could bypass suppression, duplicate a monitor wake, or lose a replacement schedule. Database tests cover these boundaries and existing integration tests still call the public heartbeat service. - This PR moves the current behavior without changing scheduling policy, schema, provider execution, or cancellation ownership. ## Model Used OpenAI Codex, based on GPT-6, with reasoning, code editing, and command execution. The session does not expose the exact model variant 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>