## Thinking Path
> - Paperclip is the open source app people use to manage AI agents for
work.
> - The server coordinates issue work and heartbeat runs.
> - The onboarding first-task route sends an assignment wake in the
background.
> - The route test removes related database rows during teardown.
> - A late heartbeat run can keep foreign-key child rows alive during
teardown.
> - This pull request drains the wake and deletes run rows in
foreign-key order.
> - The benefit is a stable test that keeps the onboarding behavior
unchanged.
## Linked Issues or Issue Description
**What happened?**
The onboarding first-task route sent a background assignment wake. The
test teardown removed parent rows before the wake-created heartbeat rows
finished.
**Expected behavior**
The test teardown should wait for the background wake and remove
heartbeat rows before it removes their parent rows.
**Steps to reproduce**
1. Run the onboarding first-task route test.
2. Repeat the test many times.
3. Observe an intermittent foreign-key error during teardown.
**Paperclip version or commit**
Commit `c30fe965920eeb7e7fb88e17574a65bed8fc01a4`.
**Deployment mode**
Local dev (pnpm dev).
**Installation method**
Built from source (pnpm dev / pnpm build).
**Agent adapter(s) involved**
Not adapter-specific (core bug).
**Database mode**
Embedded PGlite (default — DATABASE_URL unset).
## What Changed
- Stub the server adapter in the route test so the dispatched run
finishes at once.
- Drain heartbeat runs to quiescence before teardown.
- Delete heartbeat runs and child rows before their parent rows.
- Delete runtime state and company skill rows in foreign-key order.
- Keep the route behavior and all three test assertions unchanged.
## Verification
- Run `pnpm exec vitest run
src/__tests__/issue-onboarding-first-task-routes.test.ts` from the
`server` package.
- The author ran the suite 25 times with 25 passes.
- The suite reproduced the teardown foreign-key error before this
change.
## Risks
Low risk. This change affects one test file and does not change product
code or route behavior.
## Model Used
OpenAI GPT-5. The model used tool calls and code review assistance. The
exact context window and reasoning mode were not exposed in this run.
## 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] 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>
Server tests that need a real PostgreSQL process must use
./helpers/embedded-postgres.ts instead of constructing embedded-postgres
directly.
The shared helper creates a throwaway data directory and a reserved-safe
loopback port for each test database. This protects the live Paperclip
control-plane Postgres from server vitest runs; see PAP-2033 for the incident
that introduced this guard.