fix(productivity-review): anchor long_active_duration to dispatch - #1257
fix(productivity-review): anchor long_active_duration to dispatch#1257kkroo wants to merge 1 commit into
Conversation
|
🔗 Paperclip issue: BLO-19604 |
1 similar comment
|
🔗 Paperclip issue: BLO-19604 |
Use the latest dispatch timestamp for the current issue episode and avoid treating a queued, never-started holder as active work. Keep unattended and genuinely long-running dispatches detectable. Co-Authored-By: Paperclip <noreply@paperclip.ing>
5d0c3d5 to
0ade2f9
Compare
|
Heads-up on a collision, and a question about the churn case — not a review request, and I'm not asking you to change anything unilaterally. I opened #1312 for BLO-25722 before finding this PR. It targets the same reported symptom (BLO-23547's "13h 23m unattended" for BLO-21395, where 710 of 802 minutes were queue→start latency across three sequential runs) by a different route, and both of us rewrite the same block of For clarity on what is not in conflict: #1268 / #1188 are complementary to both of us. Their The substantive question. If that's a deliberate trade — re-dispatch churn is better caught by I'd rather land one of these than both. Applied naively together the anchor reset and the interval subtraction compound into a much larger exclusion than either of us intended, and this detector's whole failure mode is over-narrowing. Your call on which — happy to close mine. — CTO (Paperclip agent), re BLO-25722 |
|
Update with measured evidence, since master moved under both of us. Not a review request, and nothing here asks you to change #1257 unilaterally — it's the data I'd want before ruling.
#1257 composes cleanly with it — measured, and this favours #1257. Merged #1312 did not. The naive merge went red on your side of the house — master's The generalisable bit, which applies to any change in this area including yours: On the churn case — I asserted this before without testing it, so I checked properly. From the diff, That is the actual trade-off, and it's a legitimate one to take deliberately: a run dispatched 30 min ago is live work, and anchoring there is defensible. The cost is that an issue churning through many short dispatches over days stops being visible to this trigger — which is the BLO-23547 shape (3 dispatches, 2–5h apart). My position is unchanged: this is your call, not mine. 24 lines beats ~190 if the churn case is genuinely covered elsewhere or judged not worth covering, and I'll close #1312 and say so on BLO-25722. If you'd rather keep the churn coverage, #1312 is merge-ready now. What I'd like to avoid is both landing blind to each other, since they touch the same block and now the same ratio. |
|
Pointer, not a nag — moving this conversation to where it's actionable. I'd left two comments here and never actually put the decision in your review queue, which was the wrong routing on my part. I've now requested you as a reviewer on #1312 and stated the position and a default there: #1312 (comment) Short version: #1312 is green and Ally-clean at head; the only open question is which of these two lands. If #1257's dispatch re-anchor is a deliberate trade you've already weighed, say so and I'll close #1312 — yours is 24 lines against my ~180. Otherwise I'll merge #1312 after 2026-08-13T10:00Z UTC so the live false-positive stops, and this PR can be rebased or closed either way. |
|
Closing as stale — this draft can no longer be landed as a diff. Measured against master
At that distance the surrounding code has moved out from under the patch, so "resolve the conflicts" would mean rewriting it against a codebase it was never written for — not merging it. Reopening is cheap if the branch is still wanted; the commits are untouched. Closing the PR does not close the underlying issue. Where this PR referenced a BLO issue, that issue remains the record of intent and the place to re-implement from, against current master. No judgement here on whether the original problem still exists — I did not verify that per-PR, and it should be re-checked before any re-implementation, since some of these may already have been fixed independently. |
Thinking Path
Linked Issues or Issue Description
Refs: #1036 (app-authored predecessor; left unchanged)
Refs: BLO-19604
Problem:
long_active_durationusedissues.startedAt/executionLockedAt, which records checkout rather than actual dispatch. A queued run withstartedAt = nullcould therefore make an issue appear active for hours even though the relevant work was never dispatched.Expected behavior: measure an episode from the latest dispatched run in the current checkout episode. A current queued, never-started holder should not count as active work; an issue with no execution attempt, or a dispatched run that truly exceeds the threshold, should still be reviewable.
What Changed
max(heartbeat_runs.started_at)instead of inferring dispatch time from the capped, creation-ordered run sample.long_active_durationto that latest in-episode dispatch.Verification
pnpm --filter @paperclipai/server exec tsc --noEmit— passed.pnpm --filter @paperclipai/server exec vitest run src/__tests__/productivity-review-service.test.ts— 101/101 assertions passed before the embedded-PostgresafterAllcleanup exceeded its pre-existing 60-second hook timeout.pnpm --filter @paperclipai/server exec vitest run src/__tests__/productivity-review-service.test.ts -t 'keeps long_active_duration once a real dispatch exceeds the threshold'— 1/1 assertion passed; the same teardown timeout occurred afterward.Risks
Model Used
OpenAI GPT-5 via Codex agent, tool-assisted code inspection, implementation, and local validation. Exact model context-window metadata is not exposed by this environment.
Checklist