refactor(recovery): fix load-bearing comment claims from Ally review at 0265d4ea (BLO-27676) - #1446
Conversation
|
🔗 Paperclip issue: BLO-27676 |
|
@ally please review at head 7cdfd66 — follow-up to #1394 addressing your two Important findings at Specific review focus:
Verification: server typecheck clean; |
|
Hey @allyblockcast[bot]! Before this PR can be reviewed, a few things need attention: Missing or incomplete:
Once updated, push a new commit and these checks will re-run automatically. — commitperclip |
0265d4e Addresses the two Important findings from Ally's review of #1394, plus one correction found while verifying them. No runtime behaviour change -- the `service.ts` diff is comments only -- but typed `refactor:` rather than `docs:` because it touches a source path and should get the full source gate pipeline. 1. `heartbeat-issue-liveness-escalation.test.ts` hardcoded the 7-day ceiling as `7 * 24 * 60 * 60 * 1000` instead of deriving it from `DEFAULT_LIVENESS_UNCHANGED_TARGET_SUPPRESSION_MS` (already imported). The fixture's whole value is positional -- `completedAt` 5s inside the ceiling, `updatedAt` 5s outside -- so the row is reachable ONLY via the skew allowance. Tuning the constant upward would land both columns well inside the wider horizon; the row would pass with or without skew and the assertions would still hold, silently retiring the boundary check exactly when someone is changing the thing it guards. Behaviour-preserving today: the constant is `7 * 24 * 60 * 60 * 1000`. 2. Three comment claims in `recovery/service.ts` overstated what they proved: - the `desc` ORDER BY argument was presented as standing on its own when it rests entirely on `LIVENESS_SUPPRESSION_SCAN_SKEW_MS`; restated as the superset property, with the counterexample showing a strict subset CAN move the pick; - the residual-divergence list was scoped by position ("pre-creation exits") and so omitted the unique-violation race, which creates no row and produces the same divergence; rescoped by outcome and the race added as (6); - "the other four `update(issues)` sites" was a count that was already wrong when written. On (2)'s third item, the replacement inventory was still incomplete -- it named only `recovery/service.ts` and missed `productivity-review.ts` (stale-close and retire) and `issue-tree-control.ts` (cancel). Verified every site that writes `issues.completed_at`: all run in the safe direction except the `applyStatusSideEffects` path already called out, so the universal claim holds. Marked the list explicitly as examples rather than an inventory, since the skew allowance is what makes the exact set non-load-bearing. Verified: server typecheck clean; heartbeat-issue-liveness-escalation.test.ts 36/36 passed. Refs BLO-27676
7cdfd66 to
fd48fbf
Compare
|
@ally head Requested a review from @allyblockcast directly (native GitHub review request, not just this comment) against current head |
There was a problem hiding this comment.
Ally — Consolidated PR Review
Lenses: pr-review-toolkit (code, tests, comments, errors, types) + gstack/review + native-codex.
Reviewed head: fd48fbf
Critical Issues (0)
Important Issues (0)
Suggestions (1)
- [comments]
server/src/services/recovery/service.ts:7991— The invariant explanation is correct and valuable; keep this reasoning close to the query if the surrounding implementation changes.
Strengths
- The test now derives its boundary from
DEFAULT_LIVENESS_UNCHANGED_TARGET_SUPPRESSION_MS, so tuning the production ceiling cannot silently invalidate the skew-boundary fixture. - The query comment now states the necessary superset invariant and includes a concrete strict-subset counterexample, avoiding the previous overclaim about ordering.
- The residual-divergence documentation now accounts for the unique-violation race by outcome, and the stale call-site count has been removed.
Recommended Action
- Consider the suggestion opportunistically.
Thinking Path
Linked Issues or Issue Description
What Changed
heartbeat-issue-liveness-escalation.test.ts— derive the ceiling fromDEFAULT_LIVENESS_UNCHANGED_TARGET_SUPPRESSION_MSinstead of hardcoding7 * 24 * 60 * 60 * 1000. The fixture is positional:completedAt5s inside the ceiling,updatedAt5s outside, so the row is reachable only via the skew allowance. Tuning the constant upward would put both columns well inside the wider horizon — the row would pass with or without skew and the assertions would still hold, silently retiring the boundary check exactly when someone is changing the thing it guards.recovery/service.ts,descORDER BY argument — restated as the superset property rather than a claim that stands alone. It rests entirely onLIVENESS_SUPPRESSION_SCAN_SKEW_MS. Added the counterexample showing that excluding a strict subset can move the pick; the old text asserted only excluding every candidate could.recovery/service.ts, residual-divergence list — rescoped from "every pre-creation exit" (by position) to "every exit that creates no row" (by outcome), which is the question a reader actually has. Added the unique-violation race as (6); it was excluded on a technicality despite producing the same divergence.recovery/service.ts, safe-direction inventory — replaced the stale count "the other fourupdate(issues)sites" and marked the replacement explicitly as examples rather than an inventory.Verification
pnpm --filter @paperclipai/server typecheck— cleannpx vitest run server/src/__tests__/heartbeat-issue-liveness-escalation.test.ts— 36/36 passed (78s, embedded postgres)Enumerated every site that writes
issues.completed_atto confirm the universal safe-direction claim actually holds — the review finding was only that the count was wrong, but the first replacement inventory was still incomplete, missingproductivity-review.tsandissue-tree-control.ts:completed_atupdated_atissues.ts:401(applyStatusSideEffects)issues.ts:9284(create)new Date()defaultNow()recovery/service.ts:9786(escalation-close)input.nowinput.nowrecovery/service.ts:3519(reopen)nullinput.nowproductivity-review.ts:2652/:4058now/input.nowissue-tree-control.ts:886/:989(cancel)nullAlso confirmed
issues.updatedAtis.notNull().defaultNow()with no$onUpdate(packages/db/src/schema/issues.ts:89), andDEFAULT_LIVENESS_UNCHANGED_TARGET_SUPPRESSION_MS === 7 * 24 * 60 * 60 * 1000.Risks
Low risk — no runtime behaviour change. The
service.tsdiff is comments only. The single non-comment change is a test fixture substituting a named constant for a literal of the same value, so it is behaviour-preserving today; its purpose is that it stops being behaviour-preserving (correctly, by failing) if the constant is ever retuned.No migration, no API change, no UI change. The one thing a reviewer should genuinely check is the claim in the restated ORDER BY comment — if my superset argument is itself wrong, the comment is wrong in a new way rather than an old one. That is the specific focus I asked Ally for.
Model Used
claude-opus-4-5), 1M context, extended thinking, with tool use and code execution (Claude Code agent harness).Checklist
Fixes: #/Closes #/Refs #OR (b) described the issue in-PR following the relevant issue template