Files
PaperClipAI/server
DottaandClaude Opus 5.5 c6e4ed1547 feat(recovery): settle a claimed wake whose run finished without settling it (#19934)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - A wake request is claimed by the run that handles it, and that run
marks it finished.
> - In a K4 chaos wave (#19927), native restart recovery blocked a run
and ended it, but left its assignment wake `claimed`. Nothing ever
released it.
> - The durable-ownership plan settles such records on one shared path,
by proof, never by age.
> - This pull request registers a settle for `wake_request_claimed`. It
is Phase 2's second kind and is stacked on the accepted-result lease PR.
> - The benefit is that no run-ending path can strand a claimed wake.

## Linked Issues or Issue Description

Refs #19831 (plan), #19861 (registry), #19927 (the data that found
this). Stacked on #19933 (it adds the `settle` hook).

**What happened?**
Run `7c45860b…` failed with `native_restart_recovery_blocked`
(`execution_recovery_budget_exhausted`) at 23:19:41. Its wake
`6b3c4cce…` stayed `claimed` until the end of the wave (23:44 and
later). Rule I2 flagged it.

**What did you expect?**
A claimed wake ends when its run ends, with the run's outcome.

**Steps to reproduce**
1. `node cli/node_modules/tsx/dist/cli.mjs tests/restart-chaos/main.ts
--env local --faults K4 --k4-hold-max-seconds 600 --tasks 6
--concurrency 3 --seed 9203 --keep`
2. Look for `agent_wakeup_requests` rows with status `claimed` whose run
is terminal.

## What Changed

- New `recovery/wake-request-claimed-settlement.ts`: when the owner run
is terminal, and for a native run its coordinator is `committed` or
`terminal_failure`, the claim gets the run's outcome. That is
`completed` for a succeeded run and otherwise the run's status, as run
completion and native terminal projection already do. It is
compare-and-swap on the claim (id, run, status `claimed`).
- `ownership-registry.ts`: `wake_request_claimed` registers that settle.
- `native-finalization-reconciler.ts`: the pass log line includes the
settled count per kind.

## Verification

- `cd server && npx vitest run
src/__tests__/ownership-reconciliation-report.test.ts`: 17 pass,
including the new case. It covers a blocked native run, a native run
whose projection is still pending (kept), a succeeded legacy run, a live
run (kept), and a read-only pass (no change).
- Red/green (test written after the code): the new test fails on master
and passes here.
- Server typecheck passes.

## Risks

- No persisted shape changes, so there is no previous-release story
beyond this: claims saved by an older release are settled the same way.
- Race with the run's own settle: it waits for a native coordinator to
be final. For a legacy run, both write the same status, so the race is
idempotent.
- No change adds work before `turn.start`.

## Model Used

- Claude Opus 5.5 (`claude-opus-5-5`), Anthropic, in Claude Code with
tool use (shell, file edits).

## 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
- [ ] I will address all Greptile and reviewer comments before
requesting merge

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-07 21:18:22 -06:00
..