This article discusses critical considerations for system design related to readiness checks and initial user onboarding experiences. It highlights common pitfalls where health checks can give false positives and how defaults in production code can break first-run paths, emphasizing the need for robust verification mechanisms that validate actual code execution and system state rather than relying on superficial signals.
Read original on Dev.to #architectureThe article focuses on two primary failures encountered during the development of a 'first-run' experience for a product called Vodou, which involved injecting local memory into other chat products. These failures expose deeper architectural issues around how systems report their readiness and how initial configurations interact with production code paths. Understanding these pitfalls is crucial for building reliable and user-friendly systems from the ground up.
A common mistake in system design is relying on a readiness signal that doesn't truly confirm the active execution of the target code. The author's initial approach used a `connected` boolean from a WebSocket layer, which Chrome's network stack would answer even if the service worker was suspended. This led to a false positive, where the system appeared ready, but the actual worker responsible for the task was dormant. This highlights the importance of ensuring that readiness checks are answered *only* by the component that will perform the work.
Principle for Robust Readiness Checks
A readiness signal must be answerable only by the layer that will perform the actual work. If an intermediary (proxy, network stack, cache) can produce an affirmative answer without your application code executing, the signal is measuring the wrong thing. Implement checks that require active code execution and a unique, dynamic response (e.g., including a nonce or uptime) to verify liveness and readiness.
The second failure involved a first-run path that called the same injection logic as a normal user, but this path was behind a master toggle that was off by default on a fresh install. This meant the demo would silently fail for new users, as production code correctly declined the operation, but with no error reporting. This points to a critical architectural oversight: first-run paths are the only code that executes with every setting at its factory default value. Production assumptions about activated features or configurations can break onboarding flows.
Designing for First-Run Experiences
No step in a first-run path should read a setting whose default value causes that step to fail. If onboarding uses production code, it inherits production's assumptions about pre-existing configurations, which are often untrue for a fresh installation. Consider dedicated, simpler paths for onboarding that do not depend on optional features being enabled, or ensure defaults are conducive to a successful first run.
curl -s "localhost:8080/healthz?nonce=$RANDOM"; echo
kill -STOP "$(pgrep -f my-worker)"
curl -s --max-time 3 "localhost:8080/healthz?nonce=$RANDOM"; echo "exit=$?"
kill -CONT "$(pgrep -f my-worker)"The article suggests practical tests to validate these principles: using `curl` with a `nonce` and temporarily suspending the worker process (`kill -STOP`) to verify that the health check truly fails when the process is not executing. It also recommends SQL queries to audit onboarding step completion against actual evidence, rather than just function calls, to detect silent failures.