Skip to content

[Frontend][Inbox] Scope-replacement residuals: clear isScopeReplacement only on an applied response; eyebrow counts ignore replacement (from PR #2484 review) #2501

Description

@Chris0Jeky

Tracked residuals from the fresh-context review of PR #2484 (#2044, retained Inbox rows after same-scope refresh failures). The HIGH (mount load not treated as a scope replacement) was fixed in that PR; these were classified non-blocking.

MEDIUM — isScopeReplacement is cleared on a resolution the store discarded. useInboxOrchestrator.ts (~363-373 at head 1900e90) treats "the fetchItems promise resolved and my request id is still latest" as "the new scope's rows are in the store". The store has a second guard the orchestrator does not mirror: captureStore.ts (~151, 167) drops a list response when observedListWriteGeneration !== latestListWriteGeneration. Scenario: switch board A to B; while the replacement fetch is in flight, submit a capture from the nib (dispatchCapture is not gated on loadingList); recordCaptureWrite bumps the write generation and unshifts the new summary onto board A's list; the replacement fetch resolves, the store discards it, but the orchestrator's guards pass and it clears isScopeReplacement, so board A's rows show under board B's label. The follow-up loadInbox() normally corrects it; if that follow-up fails the wrong-label state persists. Fix direction: fetchItems should report whether it applied the response (or expose the generation) so the orchestrator only clears the flag on an applied response.

MEDIUM — header eyebrow counts ignore scope replacement. PaperInboxView.vue (~98, 484-494): useInboxCounts(items) is unconditional, so while isScopeReplacement is true the eyebrow still renders pending/total from the retained old-scope rows next to the new scope's disclosure label. Pre-existing, but it makes "retained rows stay hidden during a replacement" true only of the table.

LOW — no visible in-flight affordance during a same-scope refresh with retained rows (PaperTriageTable.vue ~539, 555): only aria-busy changes; rows stay actionable against possibly stale data.

Coordination: this seam (useInboxOrchestrator.ts generations, captureStore.ts pollers) is also touched by #2455 / #2457 / #2458 / #2464. isScopeReplacement is a third piece of state only loadInboxInternal clears — whoever picks those up should know.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Priority VMeta-tracking, archival consistency, historical context.bugSomething isn't workingfrontendPrimary implementation impact in Vue/TypeScript UI and client runtime.uxDiscoverability, accessibility, interaction model, and user workflow quality.

    Projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions