mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-10-23 09:07:46 +02:00
5fdbdb9fbdf9ff87f7ad68c803aed654e2d0cffa
3
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
8db826d18a |
fix(issues): cycle-aware issue_blockers_resolved after terminal reset (#11979)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - Agents resume blocked work through the `issue_blockers_resolved` wake when every durable blocker is `done` > - That wake is level-triggered: one ready state produces one wake, shared by the issue update route, workspace-finalize backstop, and periodic liveness backstop > - The ready-state key hashed only the dependent id and blocker set, so it ignored a later reset from a terminal status back into `blocked` > - After that reset, completing the same blockers found the previous cycle's completed wake and suppressed the new continuation > - This pull request folds the dependent's `blockedTransitionAt` into the ready-state key, with compatibility for old no-cycle keys > - The benefit is that a reset blocked issue receives exactly one new wake without watchdog status repair or a change to blocker edges ## Linked Issues or Issue Description Refs: https://github.com/paperclipai/paperclip/issues/5985 Refs: https://github.com/paperclipai/paperclip/issues/6555 Related: https://github.com/paperclipai/paperclip/pull/8009 Related: https://github.com/paperclipai/paperclip/pull/11570 This change does not auto-flip `blocked` to `todo`. The wake is the continuation. It also does not treat cancelled blockers as resolved. **What happened?** A blocked assigned issue that was previously `done` or `cancelled`, then reset to `blocked` on the same blocker set, did not receive `issue_blockers_resolved` when those blockers later returned to `done`. A completed wake from the previous cycle reused the same level-triggered state key and suppressed the new wake. Route-time emit, workspace-finalize backstop, and periodic liveness backstop all used that helper. **Expected behavior** When every durable blocker is `done`, a currently `blocked` assigned issue must receive exactly one valid `issue_blockers_resolved` continuation for the current blocked cycle. A completed wake from an earlier cycle must not suppress it. Watchdog `blocked` → `todo` repair must not be required. **Steps to reproduce** 1. Assign issue B, block it on issue A, mark A `done`, and let B receive `issue_blockers_resolved`. 2. Mark B `done`. 3. Reset A to `todo` and reset B from `done` to `blocked` on the same A id. This refreshes `blockedTransitionAt`. 4. Mark A `done` again. 5. Observe that B stays `blocked` with no new `issue_blockers_resolved` wake. **Paperclip version or commit** `master` at `cc42a67e7e9e8eb183097afc8ff4ebfa694fb3e0` **Deployment mode** Self-hosted server ## What Changed - Extend `buildIssueBlockersResolvedWakeStateKey` so the digest includes the dependent's `blockedTransitionAt` as UTC ISO-8601, or `none` - Thread `blockedTransitionAt` through `listWakeableBlockedDependents`, both route emit sites, and both backstop candidate selects - Keep compatibility: new cycle-aware keys suppress in idempotent statuses; old no-cycle state keys suppress when in-flight, or when completed and `requestedAt >= blockedTransitionAt` (or the cycle is null); legacy per-edge keys stay in-flight-only - Do not rewrite `blockedByIssueIds`, auto-flip `blocked` → `todo`, or delete historical wake rows - Add helper, route, restore, chained dependent, and backstop tests for the reset cycle ## Verification ``` pnpm --filter @paperclipai/server exec vitest run \ src/__tests__/issue-dependency-wakeups-routes.test.ts \ src/__tests__/heartbeat-issue-liveness-escalation.test.ts \ src/services/issue-dependency-wakeups.ts \ src/services/issue-dependency-wakeups.test.ts ``` Local result: all named tests passed (helper 9, routes 8, liveness 26). ## Risks - Deploy overlap: in-flight and same-cycle completed wakes still exist under the old no-cycle key. The lookup keeps those as suppressors so this change does not enqueue a duplicate in the current cycle. - A completed old-key wake from before the current `blockedTransitionAt` no longer suppresses. That is the intended fix. - No schema migration. Rollback is revert of this PR. - This does not change cancelled-blocker semantics or watchdog `blocked` → `todo` repair. > For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and discuss it in `#dev` before opening the PR. Feature PRs that overlap with planned core work may need to be redirected — check the roadmap first. See `CONTRIBUTING.md`. ## Model Used - Provider: xAI - Model: Grok 4.6 - Tool use and code execution: yes - Human-authored: no ## 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 - [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> |
||
|
|
e0e503e1bc |
fix(server): make blockers-resolved wake dedup level-triggered (#11732)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Paperclip uses issue dependencies to pause work until blockers reach a ready state. > - A blocked issue with several blockers can miss its wake when the final blocker completes. > - The wake deduplication used a historical per-edge key, so an old completed wake hid the current ready state. > - This pull request adds a level-triggered key for the sorted set of blocker issue ids and uses one helper for all wake paths. > - The benefit is that the final blocker wake can repair a missed wake, while repeated reconciliation stays bounded. ## Linked Issues or Issue Description Refs #8009, #7853, and #6719. These public pull requests cover related dependency-wake and deduplication behavior. This pull request fixes a separate multi-blocker state-key gap. **What happened?** A blocked issue with multiple blockers received no `issue_blockers_resolved` wake when the final blocker completed. An earlier completed per-edge wake suppressed the wake for the current all-ready state. **Expected behavior** The final blocker completion must emit one wake for the current ready state. A later reconciliation pass must not emit a second wake for the same state. **Steps to reproduce** 1. Create a blocked issue with at least two blocker issues. 2. Complete one blocker and record its completed per-edge wake. 3. Complete the final blocker. 4. Run the route-time or reconciliation wake path. 5. Confirm that one level-triggered wake exists for the sorted blocker set. **Paperclip version or commit** `eed1e5cad91a37547e1b521232da04b9ddb316f0` **Deployment mode** Local dev from source. ## What Changed - Add a SHA-256 level-triggered idempotency key from the sorted blocker issue ids. - Share one deduplication helper across route-time, finalize-time, and periodic wake paths. - Treat state-key rows with idempotent statuses as duplicates. - Treat legacy per-edge rows as duplicates only while they remain in flight. - Record skipped route-time wakes without suppressing later finalize-time or periodic wakes. - Add regression coverage for a completed earlier-blocker wake and a second reconciliation pass. ## Verification - Run `npx vitest run server/src/__tests__/issue-dependency-wakeups-routes.test.ts`. - Run `npx vitest run server/src/__tests__/heartbeat-issue-liveness-escalation.test.ts`. - Run `npx vitest run server/src/__tests__/heartbeat-dependency-scheduling.test.ts`. - Run `npx vitest run server/src/__tests__/issue-rewake-throttle.test.ts server/src/__tests__/recovery-stale-issue-lock-sweep.test.ts`. - Run `tsc --noEmit` on the touched files. ## Risks The change alters wake deduplication for dependency reconciliation. The new key uses the full sorted blocker set, so a change in that set permits a new wake. The regression tests cover the missed-final-blocker case and repeated reconciliation. ## Model Used OpenAI Codex, GPT-5, tool-use model with code execution and repository review support. ## 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 - [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> |
||
|
|
7bfaaadcb8 | Add dependency wake reconciliation backstop (#8943) |