Keep the two statements separate
Store the confirmed record with its identity, status, and confirmation time. When an external status arrives, retain its value and observation time separately. If it conflicts, expose a reconciliation route; do not discard the confirmed record just because a newer UI event happened.
The included reducer uses React's useReducer pattern only as a way to calculate next state. It treats freshness as an application-supplied threshold, not as proof that either source is authoritative.
Test the state model
Run the framework-independent tests:
node --test sites/reactjsx.com/evidence/P163/stale-external-status-state.test.mjs
They verify that a conflicting observation remains separate, an old observation is labeled stale, a mismatched record is ignored, and only a matching reconciliation can replace confirmed state. They do not issue requests or inspect a real server.
Announce the difference without moving focus
The illustrative JSX uses a role="status" message and a reconciliation link. WCAG 2.2 Success Criterion 4.1.3 covers status messages that can be programmatically determined without receiving focus. The example has not been browser- or assistive-technology-tested; the application still needs to test its own language, focus order, route, and integration.
For returned server values, see Should React Refetch or Reconcile Returned Server Data After a Mutation?. For a background refresh while someone edits, see Preserve an Operator Draft During Background Refresh. For an unknown mutation result, see Show a Request Retry With an Unknown Outcome.
Does this component protect the backend or decide which system is right?
No. It models client-visible state only. The backend must enforce authorization, record authority, concurrency, and reconciliation rules.