Files
PaperClipAI/server
929e840595 fix(server): schedule routines without heartbeat polling (#17840)
<!-- entire-trail-link-start -->
https://entire.com/gh/paperclipai/-/trails/47/changes/paperclip/47
<!-- entire-trail-link-end -->

## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Routines create work at saved cron deadlines.
> - The heartbeat still wakes the routine worker when nothing is due.
> - Its old next-deadline query also drops overdue work left by capped
catch-up.
> - Removing the heartbeat alone can strand that work and miss company
reactivation.
> - This pull request uses saved deadlines and committed producer
changes.
> - Idle routine scheduling stops querying until a change, retry, or
real deadline.

## Linked Issues or Issue Description

Refs #16514. Merged prerequisite: #17836. Related Cloud wake contract:
#16215.

**What happened?**

Every heartbeat wakes the routine scheduler. The next-deadline query
excludes overdue triggers. A 27-tick hourly backlog loses its deadline
after the first 25-run pass. Company and budget lifecycle changes also
lack routine schedule signals.

**Expected behavior**

Use the actual next saved deadline. Retain overdue work. Refresh after
supported producer transactions commit. Keep idle schedules quiet
between obligations.

**Steps to reproduce**

1. Create an hourly routine with capped catch-up and 27 overdue ticks.
2. Run the registered worker once. The base processes 25 ticks and
reports no next wake.
3. Create a future schedule and pause or reactivate its company. The
base does not refresh its registered deadline until another wake.

## What Changed

- Remove only the routine worker wake from the heartbeat tick.
- Put routine eligibility and the next-deadline read in
`routineService`. Include overdue triggers. Keep trigger/routine company
scope consistent and require an active company.
- Reuse `registerDeadlineWork` for retries, request generations, and
passive drain behavior. Narrow its coordinator type to the `register`
method it uses. Existing consumers keep the same runtime behavior.
- Signal routine work from manual schedule invocation, company
pause/resume/archive/delete, and budget-induced company pause/resume.
Existing routine and trigger producers retain their transaction signals.
- Stop between trigger batches during drain/shutdown. Finish a claimed
batch so its advanced timestamp does not discard admitted work.
- Add real PostgreSQL lifecycle tests and extend startup/query fixtures.
Add a validated external database option to the company suite, including
migrations and client closure.
- Record producer coverage and limits in
`doc/plans/2026-10-27-routine-schedule-sleep.md`.

## Verification

- **417 passing unique cases across 14 complete files**, no skips, on
accepted source `4659ef76d398193b15e7812d4a97f3da3b743226`. Coverage
includes the real deadline worker, database eligibility queries, routine
services/HTTP/routes/plugins, budget/company producers, git/device
fixtures, startup and shared coordinator.
- The first combined run passed 416 cases and had one UUID HTTP
authorization timeout at its unchanged 20-second limit. One fresh
complete 13-case E2E diagnostic passed (the affected case took 425 ms).
No assertions, timeouts or production source were changed; the initial
timeout's cause is not established.
- Database build, production server typechecking/build, module
boundaries, target migration order and Runner profile identity pass.
Fresh PostgreSQL 17 fixtures applied all 412 journal entries through
index 413; all selected test hashes and temporary fixture imports were
restored exactly.
- Normal parent merges preserve the tested production and test source.
Historical acceptance and review corrections remain in [the routine
audit](doc/plans/2026-10-27-routine-schedule-sleep.md).
- No full local repository-suite, deployed suspend/wake, external alarm,
live provider or fleet-cost claim. Final-head CI, security, exact-head
Greptile 5/5 and actionable Ponytail findings remain separate merge
gates.

## Risks

- Company pause now prevents due routine claims, matching the prior
deadline query. Rows remain saved for reactivation. Existing routine
reactivation, project-pause skip records, cron, timezone, catch-up, and
concurrency policies remain with the routine owner.
- Signals cover supported service writers in one process. Independent
SQL writers and other replicas need their own integration.
- This proves worker quiet, not host/database suspension or fleet
savings. Cloud idle proof and external wake coverage are unchanged.
- Issue-monitor and legacy-agent-timer polling remain separate duties.
This slice does not finish the full migration stack or its CI/review
work.

## Model Used

OpenAI Codex (GPT-6-based coding agent), using repository inspection,
ordinary Git merges, source-composition proofs, PostgreSQL fixtures and
local lifecycle tests. No subagents were used in the current
reconciliation.

## 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>
Co-authored-by: Codex <noreply@openai.com>
2026-10-29 08:08:04 -05:00
..