When I started building a status page for a newly released messaging app, I thought the job was simple: answer whether the app was available.
That assumption lasted about one afternoon.
“Available” turned out to hide several different states:
- a store listing exists;
- the listing belongs to the expected publisher;
- the page shows Install, Pre-register, or Not available;
- the user can create or use the required account;
- the network path works in the user's region;
- the feature has actually rolled out to that account;
- the current build supports the feature being discussed.
A single boolean could not represent any of this without misleading somebody.
Model the decision, not the headline
I replaced the boolean with a small set of explicit observations:
type StoreState =
| "not_found"
| "pre_register"
| "install"
| "region_blocked"
| "unknown";
type Evidence = {
observedAt: string;
sourceUrl: string;
publisher?: string;
storeState: StoreState;
accountAccess: "works" | "blocked" | "untested";
featureRollout: "present" | "missing" | "unknown";
};
The important part is not the union type. It is the refusal to collapse different questions into one confident answer.
For example, a reader in mainland China may be able to see an App Store page while still being unable to finish sign-in. Another reader may install the same build but not receive a feature flag yet. Both experiences are real, and neither is explained by “launched globally.”
Put time next to every changing fact
App availability is a cache with a very short half-life. I now attach an observation date to store state, publisher identity, version history, and official help pages. If an article says “there is no standalone app” but a verified publisher releases one later, the old article is not necessarily dishonest; it is simply date-bound.
This also changed the UI. Instead of a large green “available” badge, the page can say:
iOS listing verified on 12 August 2026. Android store state still varies by region. Account access was not independently tested.
That sentence is less exciting, but much more useful.
Separate safety evidence from marketing claims
Encryption language creates a similar problem. A product announcement, a store description, and a third-party security review are not equivalent evidence. I keep those layers separate and avoid converting “encrypted” into “safe.” Publisher identity, download source, account recovery, metadata behavior, and implementation review are different checks.
I keep the live decision pages for this experiment at WexChat Pro. It is an independent reference site, not an official X product. The broader engineering lesson applies to any fast-moving product: model what the user must decide, preserve the source and timestamp, and let uncertainty remain visible.
A status page should not merely report a launch. It should help a real person decide what to do next.
Top comments (0)