Commit Graph
2 Commits
Author SHA1 Message Date
0f6f0a3fee fix(server): schedule issue monitors without heartbeat polling (#17863)
<!-- entire-trail-link-start -->
https://entire.com/gh/paperclipai/-/trails/56/changes/paperclip/56
<!-- entire-trail-link-end -->

## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Issue monitors save a future check on an existing issue.
> - The heartbeat timer still scans monitors on every tick, even when
none are due.
> - The saved deadline and claim already provide durable scheduling
state.
> - This pull request gives monitors their own deadline worker and
connects state changes to it.
> - Idle monitor work stops querying. Existing admission and recovery
rules remain in force.

## Linked Issues or Issue Description

Refs #17840, #16325. Related: #17171 addresses rearming a monitor after
its admitted run fails. This PR changes when monitor inspection runs and
follows the merged routine prerequisite.

**What existing behavior does this improve?**

Issue-monitor scheduling and idle database use.

**Current behavior**

Heartbeat ticks call the combined agent and monitor sweep. The existing
next-deadline query only retains future monitors. Polling covers overdue
leftovers, stale claims, and changes that make a saved monitor eligible.

**Proposed behavior**

Use the shared deadline worker. Retain overdue work with bounded
retries. Wake after committed changes to monitor state, issue
eligibility, company state, or native ownership. Keep legacy agent ticks
separate for the next slice.

## What Changed

- Add monitor-specific sweep and deadline methods to the existing
scheduling owner. Keep the manual combined method.
- Include overdue work and the strict five-minute claim fence. Exclude
active native owners until their state changes.
- Register monitors with the shared deadline worker. Heartbeat ticks
wake only the legacy agent timer worker.
- Connect direct issue-state writers and existing execution-control
notifications to monitor work. Checkout uses a short transaction around
its existing CAS. Provider work stays outside it.
- Add real database lifecycle tests and retain routine, startup,
admission, execution-control, and native-projection coverage.
- Record the obligation, producer inventory, recovery behavior, and
limits in `doc/plans/2026-10-27-issue-monitor-sleep-audit.md`.

## Verification

- **1,233 passing cases in 35 complete files**, no skips, on accepted
source `c24aadfc91e9394d73c799f9e05fc67202160557`. Coverage includes
real monitor scheduling/admission, native settlement, committed
producers, retained routines and all shared deadline consumer
integration suites.
- Database build, production server typechecking/build, module
boundaries, target migration order and Runner profile identity pass.
Twenty-four fresh PostgreSQL 17 schemas plus per-file fixtures applied
all 412 journal entries through index 413; every selected source hash
and temporary fixture import was restored exactly.
- Normal parent reconciliation preserves master's admitted-wake result
and scoped issue deletion while keeping committed monitor notifications.
All other paths match the automatic merge; packages remain byte-exact to
the qualified parent. The final routine-parent publication changes only
its audit.
- Historical failures and corrections remain in [the monitor
audit](doc/plans/2026-10-27-issue-monitor-sleep-audit.md). Old
delegated-Slack rate and Runner drain CI failures are retained; the
current inherited clock fixture and package source are byte-identical to
merged #17835. Fresh final-head CI remains required.
- No full local repository-suite, live provider, deployed suspend/wake,
external-alarm, production-load or fleet-savings claim. Final-head
CI/security, exact-head Greptile 5/5 and actionable Ponytail findings
remain separate merge gates.

## Risks

- A missing producer notification can strand a monitor after polling is
removed. The audit covers ordinary writes, direct status/assignment
writers, recovery, and native ownership changes.
- The writer model is process-local. Independent SQL writers and other
replicas need a supported notification or reconciliation contract.
- Overdue work uses the configured heartbeat interval as a retry floor
for the monitor worker. New notifications during that backoff wait for
its next pass. Normal state-change bursts coalesce for one second.
- Notification fanout can inspect monitors during other active work. An
unchanged idle subsystem has no recurring monitor scan.
- The legacy agent timer still polls. Cloud sleep proofs and external
alarm coverage are unchanged.

## Model Used

OpenAI Codex (GPT-6-based coding agent), using repository inspection,
ordinary Git merges, composition proofs, PostgreSQL fixtures and
complete local integration suites. No subagents were used in this
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:40:56 -05:00
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