Skip to content

fix: guard deferred review receipts by decision locus - #2629

Merged
Chris0Jeky merged 1 commit into
mainfrom
issue-2128/defer
Sep 5, 2026
Merged

fix: guard deferred review receipts by decision locus#2629
Chris0Jeky merged 1 commit into
mainfrom
issue-2128/defer

Conversation

@Chris0Jeky

Copy link
Copy Markdown
Owner

Summary

  • Guard the onDefer decision receipt with the current Paper Review decision locus.
  • Keep successful deep-link cleanup independent from the visible receipt guard.
  • Add stale-selection and matching-locus deferred-promise regressions.

Refs #2128

Verification

  • Red-first stale-selection test failed against the unguarded baseline.
  • Mutation check (guard removed) failed the stale-selection test as expected.
  • npx vitest --run --maxWorkers=2 src/tests/views/paper/review/PaperReviewView.spec.ts -t "defer receipt" — 2 passed.
  • npx vitest --run --maxWorkers=2 src/tests/views/paper/review/PaperReviewView.spec.ts — 171 passed.
  • npx vitest --run --maxWorkers=2 — 5,713 passed, 3 skipped across 370 files.
  • npm run typecheck — passed.
  • npx eslint src/views/paper/PaperReviewView.vue src/tests/views/paper/review/PaperReviewView.spec.ts --max-warnings=20 — passed.
  • npm run build — passed; existing ineffective dynamic import warning remains.
  • git diff --check — passed.

Scope

This PR implements only TD-2128-defer. The execute and reject sibling recorders remain separate slices.

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, add credits to your account and enable them for code reviews in your settings.

Chris0Jeky added a commit that referenced this pull request Sep 5, 2026
… inherit

Review round 2. Both hoisted sentences state emptiness from an empty default
that also means "still loading" and "the read failed".
usePaperReviewSelectors initialises confidenceData to EMPTY_CONFIDENCE and
similarPastData to an empty array, clearSelectorData resets both on every
proposal switch, and a failed batch deliberately leaves them there so a partial
snapshot cannot publish; no flag distinguishes that state, and
evidenceUnavailable on ReviewRightRail is set only from the Apply-time refresh
(activeRevisionReviewUnavailable), never from the page-load batch.

Neither card can fix this. ReviewRightRail is a pure props component and the
twelve props it receives are all bound in PaperReviewView.vue, which is held by
open PR #2629. The composable does expose `loading`, but nothing threads it in.
Adding a settled prop defaulting to true would compile and change nothing on
the real surface, while presenting the defect as handled, so this commit
records the gap instead of simulating a fix.

Record it in both doc blocks, naming the three situations that arrive as the
same empty value and the one place that could tell them apart. The copy itself
is not new: the same sentences rendered inside the disclosures before #1940, so
hoisting made an existing false claim easier to see rather than creating one.

Also use the isEmpty computed for the apply-rate guard, which still read
rows.length > 0 while the rest of the template had moved on.

Refs #1940
@Chris0Jeky

Copy link
Copy Markdown
Owner Author

Review gate (Codex review credits exhausted, SC-9; D-12 ruled 2026-09-05: the Codex session's PRs are reviewed and merged by the coordinator): one fresh-context read-only reviewer (Opus 5) on head ff741827b. Verdict: SHIP.

Checked by reading: the new onDefer guard is the same locus expression already shipped for approve (explicitActiveId.value ?? activeProposal.value?.id compared with proposalIdsEqual), differing only in shape (approve early-returns, defer wraps the recorder in a positive if so cleanup still runs); proposalIdsEqual (utils/proposalIdentity.ts:9-16) is null-safe, so an absent locus suppresses rather than spuriously matches; clearProposalDeepLink (composables/useReviewProposals.ts:536-539) only replaces the route when the hash still names that proposal, so calling it unconditionally cannot yank the new selection's hash; every reviewer-initiated selection change goes through selectProposal and updates the locus; before the fix the unconditional recordDecisionReceipt re-pinned explicitActiveId to the abandoned proposal, which the stale-selection test exposes (it fails on revert); the matching-locus test is the over-suppression complement by design; two files, no new i18n keys (the deferred receipt keys already exist in en/es/it).

Findings and disposition (both LOW, none owed for merge):

  • LOW, PaperReviewView.vue:2063: no test exercises the suppressed-receipt plus hash-still-present combination (in the stale test the hash is already empty at resolve time), so the claimed cleanup independence is true of the code but unobserved. Tracked on #2128.
  • LOW, process: the head is behind main on this file (the sticky-offset block landed since) with no overlap at the receipt seam; mergeStateStatus CLEAN.

Residual (pre-existing, identical to onApply on main): if the active row leaves the filtered list mid-flight without arming the poll notice, the receipt still re-anchors the surface. Not introduced here.

Issue disposition: slice of #2128 (TD-2128-defer); onConfirmExecute (:2067-2076) and onConfirmReject (:2078-2087) still record receipts without a locus guard.

@Chris0Jeky
Chris0Jeky merged commit cf24dec into main Sep 5, 2026
35 checks passed
@github-project-automation github-project-automation Bot moved this from Pending to Done in Taskdeck Execution Sep 5, 2026
Chris0Jeky added a commit that referenced this pull request Sep 5, 2026
…s line, SC-10 scope, item-5 count, carry-forward)

Answers the docs review of PR #2693: the header points forward to the coordination-lane subsection the coordinator adds after the block lands instead of at one that does not exist yet; a corrections line retires the thirteenth block's present-tense claim that #2629 and #2654 were unmerged; the SC-10 sentence scopes the platform lane's five to its own checkpoint and leaves the ten-PR measurement to the coordinator's sweep record; item 5's caller count is the measured five; the not-shipped line carries the fourteenth block's non-ruling residuals forward; items 5 to 10 named on the #2690 bullet; one bare issue number backticked.
@Chris0Jeky
Chris0Jeky deleted the issue-2128/defer branch September 6, 2026 02:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

1 participant