Files
PaperClipAI/server
DottaandPaperclip e16de641ba fix(heartbeat): retain Stop and receipt debt after setup failure (#18776)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - The server owns execution, Stop delivery, and usage settlement.
> - A restored execution can fail during preparation.
> - A preparation failure does not prove that earlier provider work
never started.
> - Replacing its result metadata can remove an existing Stop and
falsely release its accounting hold.
> - This pull request preserves those obligations at the terminal write.
> - The benefit is honest cleanup and receipt debt without new execution
authority.

## Linked Issues or Issue Description

**What happened?**

A recovered native run can fail a configuration check before dispatch in
the new controller. The setup failure writes bootstrap metadata with
`providerWorkStarted: false`. It also replaces the previous result
metadata. This can remove a pending native Stop. Accounting then accepts
the new bootstrap flag and releases the original hold despite an
incomplete receipt.

**Expected behavior**

Keep the current run-Stop and receipt debt when setup fails after
earlier native execution. Preserve an acknowledgement that commits
during the failure write. Fresh setup that never dispatched must remain
eligible for pre-provider settlement. Keep account-identity checks
effective.

**Steps to reproduce**

1. Save admitted native execution, an active provider checkpoint, an
original held reservation, and an audited pending run-only Stop.
2. Recover the run and fail preparation with an account configuration
error before the new controller dispatches.
3. Run ordinary cost reconciliation with an incomplete receipt.
4. Observe that the base removes the Stop and releases the hold as if
the run never started.

Related: #18682 repairs exact-session Stop cleanup after restart. This
change protects setup failure before that path. #18702 handles AI
connection-request waits. #18035 proposes broader accounting policy.
#18778 separately handles retained cleanup across account changes.
Account, budget, and receipt authority are unchanged here.

## What Changed

- Mark setup-failure status writes through an internal lifecycle option.
At the atomic write, a prior coordinator attempt bound to the same run,
company and task prevents false pre-provider evidence, even with a stale
loaded profile. Lock the coordinator before the run so an in-flight
claim cannot be missed. Selected execution input alone does not imply
provider work.
- Keep genuine pre-dispatch setup eligible for settlement after fresh
native input is persisted, whether the loaded profile is current or
stale.
- Preserve only exactly bound native run-Stop fields from the current
database row during failure writes, including the intentional handoff
marker. Keep the latest acknowledgement when the update waits behind
another writer. Normal Stop delivery still advances its own metadata.
Replace unrelated stale result fields.
- Add real PostgreSQL regressions for receipt debt, original holds,
stale snapshots, late acknowledgement, fresh setup, dispatched work, and
foreign or task-scoped metadata.
- Update the execution contract.

## Verification

- On untouched master, the recovered-setup regression fails six
assertions: Stop removal, false bootstrap evidence, false accounting
settlement, lost debt, and released hold. The fresh-setup control
passes.
- A second regression fails four assertions with the first repair
present when the loaded profile lacks the current saved execution. The
atomic current-row check fixes that case.
- The focused safety selection passes. It includes real row-lock
contention. A controlled concurrent writer seeds audited acknowledgement
state while the terminal update waits. The product code retains that
state and creates no acknowledgement or provider turn. This race test
does not prove physical provider termination.
- Fresh native and legacy setup can settle without a receipt. Dispatched
native and legacy work keeps its debt. Foreign run, company, issue and
task-scope metadata stays excluded. Unrelated old result fields are
replaced.
- After the final review fixes, all three completion, Stop and
budget-cancellation suites pass: 121 tests. The exact `pnpm run
typecheck:build-gaps` entry point passes after the final source and
service-test edits. Module-boundary checks pass. An ordinary adapter
pre-provider receipt control also passes.
- Native review also found that fresh selected input could be mistaken
for prior execution. Real-admission loaded/stale cases fail against the
earlier head; a prior-attempt-only control passes. The correction uses
the bound coordinator attempt and includes a foreign-task negative.
Reservation `providerStartedAt` is stamped at reservation creation and
is not used as provider-work evidence.
- A row-lock regression also exposes a first execution claim committing
during the terminal write: the prior statement snapshot misses it and
falsely releases the hold. Locking the exact coordinator before the run
fixes that race and preserves the existing claim lock order. Concurrent
Stop acknowledgement tests remain green.
- Review found two preservation gaps. New real-database reds show
handoff classification loss and overwritten budget Stop delivery
progress. Failure-only preservation and the bounded handoff marker
address them.
- Initial helper-import and reservation-order fixture errors are
retained separately from causal failures. No assertion or deadline was
relaxed to pass the regression.
- Current-head Greptile is 5/5. The optional native review stopped
before completing and returned NEUTRAL; this is not substantive
approval. Its prior finding was reproduced and fixed. Coordinator and
independent source/evidence reviews found no additional issue; neither
is a hosted recovery test.
- These are local database tests with saved provider state. No hosted
recovery, physical provider termination, historical-state repair, or
deployment is claimed. Full repository tests and build passed in
current-head CI: 55 successful checks, three expected skips, and the
explicitly incomplete optional native review returned NEUTRAL. Required
verify and e2e aggregates passed.

## Risks

- The current database row must retain canonical Stop state while
replacing other result metadata. The preservation is limited to the same
native run, company, issue and run-only Stop scope.
- Setup-failure history checks keep uncertain work pending. They do not
create a receipt, acknowledgement, reservation or charge.
- The setup-only write option leaves ordinary adapter pre-provider
receipts unchanged. No account-identity, budget, dispatch, or provider
authorization gate is bypassed.
- Already overwritten historical state needs separate evidence and
repair. This change does not reconstruct it.
- No schema, public API, provider profile, or deployment setting changes
are required.

## Model Used

OpenAI Codex, `gpt-6.1-sol`, Extra High reasoning, with source
inspection, code execution, and regression testing. Context-window
capacity is not exposed in this session.

## 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 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>
2026-11-03 08:49:28 -06:00
..