diff --git a/5-Final/RFC0052-Notification-On-Version-Update.md b/5-Final/RFC0052-Notification-On-Version-Update.md
new file mode 100644
index 00000000..c2097a17
--- /dev/null
+++ b/5-Final/RFC0052-Notification-On-Version-Update.md
@@ -0,0 +1,304 @@
+---
+RFC: 0052
+Author: Dongbo Wang
+Status: Final
+SupercededBy: N/A
+Version: 1.0
+Area: Console
+Comments Due: 4/30/2019
+Plan to implement: Yes
+---
+
+# Notification on PowerShell version updates
+
+Today, to find out whether a new version of PowerShell is available,
+one has to check the release page of the `PowerShell\PowerShell` repository,
+or depend on communication channels like `twitter` or `GitHub Notifications`.
+It would be convenient if `pwsh` itself can notify the user of a new update on startup.
+
+## Motivation
+
+ As a PowerShell user, I get notified when a new version of `pwsh` becomes available.
+
+## Specification
+
+This feature is in the PowerShell console host, not in the PowerShell engine.
+
+### Target Goals
+
+1. No notification or update check when the running `pwsh` is a self-built version.
+No notification or update check for non-interactive sessions.
+Also, no notification when the PowerShell banner message is suppressed.
+
+2. When there is a new update, assuming you use `pwsh` every day
+and at least one interactive `pwsh` session lasts long enough for the update check,
+then you should be able to see an update notification during the `pwsh` startup on the same day of a release or the next day at the latest.
+
+3. This feature must have very minimal impact on the startup time of `pwsh`.
+This means the check for update must not happen during `pwsh` startup.
+The only acceptable extra overhead to the `pwsh` startup should just be the work related to printing the notification.
+
+4. Check for updates should not blindly run for every interactive `pwsh` session.
+For a particular version of `pwsh`, only one check at most can run to complete per day
+no matter how many interactive session of the `pwsh` are started/opened in that day.
+
+5. After a new update is detected during a successful check,
+all subsequent interactive sessions of that version of `pwsh` should show the notification at startup time.
+And subsequent checks can be avoided for a reasonable period of time, such as a week.
+
+6. `pwsh` of preview versions should check for the new preview version as well as the new GA version.
+`pwsh` of GA versions should check for the new GA version only.
+
+7. The notification and update check are not needed in some scenarios,
+such as when `pwsh` is in a container image.
+Hence, you should be able to suppress them altogether by setting an environment variable.
+
+### Non-Goals
+
+1. Notification shows up right after a new version of `pwsh` is released.
+
+ _This is not a goal._
+ Assuming you use `pwsh` interactively every day,
+ then a notification about the new release may show up on the same day,
+ but is guaranteed no later than the next day.
+
+2. If an update check detects a new release, the notification should show up in the same session.
+
+ _This is not a goal._
+ An update check should happen way after the startup of an interactive session,
+ and thus it has no impact on whether or not a notification will be shown at the startup of that session.
+ If new release is detected,
+ the subsequent interactive sessions will show a notification about that new release.
+
+3. If a new release is available, `pwsh` is able to automatically upgrade.
+
+ _This is not a goal._
+ A notification message is printed, but `pwsh` will not auto-upgrade.
+
+### Implementation
+
+This section talks about
+
+- how to control the update notification behavior
+- when to do the update check
+- how to persist the detected new release for subsequent `pwsh` sessions to use
+- how to synchronize update checks from different processes of the same version `pwsh` so that at most only one can run to complete during a day
+- how to do the update check
+- how to display the notification
+
+#### How to control the update notification behavior
+
+The environment variable `POWERSHELL_UPDATECHECK` will be introduced to control the behavior of the update notification feature.
+The environment variable supports 3 values:
+
+- `Off`. This turns off the update notification feature.
+
+- `Default`. This gives you the default behaviors:
+ - `pwsh` of preview versions check for the new preview version as well as the new GA version.
+ - `pwsh` of GA versions check for the new GA version only.
+
+- `LTS`. `pwsh` of both preview and stable versions check for the new LTS GA version only.
+
+The notification behavior is mapped to the following enum:
+
+```c#
+private enum NotificationType
+{
+ ///
+ /// Turn off the udpate notification.
+ ///
+ Off = 0,
+
+ ///
+ /// Give you the default behaviors:
+ /// - the preview version 'pwsh' checks for the new preview version and the new GA version.
+ /// - the GA version 'pwsh' checks for the new GA version only.
+ ///
+ Default = 1,
+
+ ///
+ /// Both preview and GA version 'pwsh' checks for the new LTS version only.
+ ///
+ LTS = 2
+}
+```
+
+#### When to do the update check
+
+During the startup, `pwsh` creates a `Task` of the update check work,
+but delays the task run for 3 seconds by using `Task.Delay(3000)`.
+The typical startup time for `pwsh` with a moderate size profile should be less than 1 second.
+Given that, I think it's reasonable to delay the update check work for 3 seconds,
+so that it has close-to-zero impact on the startup performance.
+
+#### How to persist information about a new version
+
+The version of new release is persisted using a file,
+not as the file content, but instead baked in the file name in the following template,
+so that we can avoid extra file loading at the startup.
+
+```none
+update__
+```
+
+A separate file is used for each supported notification type,
+indicated by the integer value of the corresponding `NotificationType` member.
+For example,
+- when the notification type is `NotificationType.Default`,
+the file name would be like `update1__`.
+- when the notification type is `NotificationType.LTS`,
+the file name would be like `update2__`.
+
+The file should be in a folder that is unique to the specific version of `pwsh`.
+For example, for the `v6.2.0 pwsh`, the folder `6.2.0` will be created in the `pwsh` cache folder (shown below),
+and the update check related files for that version of `pwsh` are put there exclusively.
+In this way, the update information for different versions of `pwsh` doesn't interfere with each other.
+
+- Windows: `$env:LOCALAPPDATA\Microsoft\PowerShell\6.2.0`
+- Unix: `$env:HOME/.cache/powershell/6.2.0`
+
+#### How to synchronize update checks
+
+The most challenging part is to properly synchronize the update checks started from different `pwsh` processes,
+**so that for a specific version of `pwsh` and a specific notification type,
+only one update check task, at most, will run to complete per a day.**
+Other tasks should be able to detect "a check is in progress" or "the check has been done for today" and bail out early,
+to avoid any unnecessary network IO or CPU cycles.
+
+For each notification type, we need two more files to achieve the synchronization,
+`"_sentinel_"` and `"sentinel-{year}-{month}-{day}.done"`.
+The `` part will be the integer value of the corresponding `NotificationType` member.
+The `{year}-{month}-{day}` part will be filled with the date of current day when the update check task starts to run,
+and they will be in the version folder too.
+
+The file `"_sentinel_"` serves as a file lock among `pwsh` processes.
+The file `"sentinel-{year}-{month}-{day}.done"` serves as a flag that indicates a successful update check as been done for the day.
+Here are the sample code for doing this synchronization:
+
+```c#
+const string TestDir = @"C:\arena\tmp\updatetest";
+const string SentinelFileName = "_sentinel1_";
+const string DoneFileNameTemplate = "sentinel1-{0}-{1}-{2}.done";
+
+static void CheckForUpdate()
+{
+ // Some pre-validation needs to happen to see if we need to do anything at all.
+ // - If the current running `pwsh` is a self-built version, let's bail out early.
+ // - Check if a file like `_update__` already exists.
+ // If so, check the `publish-date` to see if it's still relatively new, say within a week.
+ // If so, let's bail out early.
+
+ DateTime today = DateTime.UtcNow;
+ string todayDoneFileName = string.Format(
+ CultureInfo.InvariantCulture,
+ DoneFileNameTemplate,
+ today.Year.ToString(),
+ today.Month.ToString(),
+ today.Day.ToString());
+
+ string sentinelFilePath = Path.Combine(TestDir, SentinelFileName);
+ string todayDoneFilePath = Path.Combine(TestDir, todayDoneFileName);
+
+ if (File.Exists(todayDoneFilePath))
+ {
+ // A successful update check has been done today,
+ // so we can bail out early.
+ return;
+ }
+
+ try
+ {
+ // Use 'sentinelFilePath' as the file lock.
+ // The update check tasks started by every 'pwsh' process will compete on holding this file.
+ using (FileStream s = new FileStream(sentinelFilePath, FileMode.OpenOrCreate, FileAccess.Write, FileShare.None, bufferSize: 1, FileOptions.DeleteOnClose))
+ {
+ if (File.Exists(todayDoneFilePath))
+ {
+ // After grab the file lock, it turns out a successful check has finished.
+ // Then let's bail out early.
+ return;
+ }
+
+ // Now it's guaranteed that I'm the only process that reaches here.
+ foreach (string oldFile in Directory.EnumerateFiles(TestDir, "sentinel-*-*-*.done"))
+ {
+ // Clean up the old '.done' file, there should be only one.
+ File.Delete(oldFile);
+ }
+
+ // Do the real update check
+ // - Send HTTP request to query for the new release/pre-release;
+ // - If there is a valid new release that should be reported to the user, create the file `_update_`,
+ // or rename the existing `_update_` to `_update_`.
+ // ... more ...
+
+ // Finally, create the `todayDoneFilePath` file as an indicator that a successful update check has finished today.
+ new FileStream(todayDoneFilePath, FileMode.CreateNew, FileAccess.Write, FileShare.None).Close();
+ }
+ }
+ catch (Exception e)
+ {
+ // An update check is in progress from another `pwsh` process. So it's OK to just return.
+ }
+}
+```
+
+> Note: `FileOptions.DeleteOnClose` is used when opening the sentinel file,
+so the sentinel file will be removed after being used as a lock.
+
+With the file lock, only one process can get in the guarded `using` block at a given time.
+So only one process will be creating the file `_update__`, or renaming an old such file to reflect the new version.
+Yes, other processes could be looking at the old file name (when a `pwsh` session tries to print a notification),
+or working with an outdated file name (another update check tries to do a pre-validation).
+But it's fine for that to happen:
+
+- In the former case, that particular `pwsh` session will show a notification about an outdated version,
+ but the next `pwsh` session will show the right notification.
+- In the latter case, the other update check will continue and find the `.done` file already exists for today.
+
+It's possible that a `pwsh` session terminates while the update check task is still running,
+in the middle of the `using` block for example.
+Creating the `.done` file is the very last step in the `using` block.
+So if the session ends before the `.done` file is created,
+another update check will happen when the next `pwsh` session starts and finish the work.
+
+#### How to do the update check
+
+This is comparatively the easy part.
+
+- Determine the URL to use depending on the notification type.
+ - For latest preview release-info: `https:///preview.json`
+ - For latest stable release-info: `https:///stable.json`
+ - For latest LTS release-info: `https:///lts.json`
+- Send HTTP query request and parse the response.
+- If there is a new update, create the file `update__` if one doesn't exists yet;
+ or rename the existing file with the new version.
+
+#### How to display the notification
+
+`pwsh` checks to see if notification should be printed only if it's allowed to print the banner message and feature is not turned off.
+
+- Run `Directory.EnumerateFiles` with the the version directory and the pattern `update_v*.*.*_????-??-??` to find such a file.
+- If a file path is returned, then get the version information from the file name.
+- Use that version to construct the notification message, including the URL to that GitHub release page.
+- The notification message is printed with the foreground and background colors inverted.
+
+## Alternate Proposals and Considerations
+
+When thinking about how to reduce unnecessary update checks,
+the first design I had was to depend on the `Day` of the month.
+So for instance, we can check for updates every 3 days by checking `DateTime.UtcNow.Day % 3 == 0`.
+But that means in the worst case, a user won't be notified of a new release until 3 days after the release.
+That makes this feature somewhat broken from the UX perspective.
+
+Another design is to let all `pwsh`, including different versions, share the same update file,
+whose name contains both the latest stable release tag and latest preview release tag.
+When `pwsh` starts, it parses the file name, compare the latest stable/preview release version with its current version,
+and decides if a notification should be printed.
+This would reduce the number of helper files in the cache folder,
+however, with the cost of additional work at startup time for all versions of `pwsh`.
+Especially, for the latest stable or preview `pwsh` in use, it also needs to spend those extra cycles when it should not.
+Besides, I think having the helper files isolated in a version folder makes it flexible in case we need to make change to the design at a later time.
+
+We may consider to add an API in PowerShell engine to check for updates in future,
+so that other hosts can offer similar features using the API.