docs(activation): capture the denied-permission dead-end learning (#5609)#5624
Merged
Conversation
) The fourth follow-on fix to the activation wizard (#5534 -> #5600 -> #5607 -> #5609) with nothing captured, so the reusable parts were being rederived each time. Records the bug class behind #5609 — a terminal platform refusal modelled as a transient failure, which is what put a retry button on a state no retry can clear — plus four things the fix's review surfaced: classify from live platform state rather than a thrown error string; funnel every read through one accessor when a state becomes reachable at a new time; check what signal is erased when a fix reclassifies an outcome into an existing bucket; and a test DOM whose innerHTML replays the assigned string goes vacuous rather than failing. Adds an Activation Step State entry to CONCEPTS.md for the terminal-versus- retryable distinction the existing Activation Interstitial entry did not cover. Claude-Session: https://claude.ai/code/session_01SirbngHaZJc6i9jMJ5mxhF
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
It is a merged PR, not an issue, and sat in a list that otherwise reads as issues. Claude-Session: https://claude.ai/code/session_01SirbngHaZJc6i9jMJ5mxhF
Contributor
|
Preview deployment for your docs. Learn more about Mintlify Previews.
💡 Tip: Enable Workflows to automatically generate PRs for you. |
Contributor
|
Preview deployment for your docs. Learn more about Mintlify Previews.
💡 Tip: Enable Workflows to automatically generate PRs for you. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Follow-up to #5609 / PR #5615 (merged). Docs only — no code changes.
Why
This was the fourth follow-on fix to the same activation wizard — #5534 (the origin feature) → #5600 → #5607 → #5609 — with no learning captured for the area. The reusable parts were being rederived each time.
What's here
docs/solutions/logic-errors/denied-push-permission-rendered-as-retryable-failure.mdrecords the bug class behind #5609: a terminal platform refusal modelled as a transient failure. The confirm handler's'verified' | 'failed'union had no way to say "do not retry", andfailedis what puts a "Try again" button on screen — so a denied notification permission, which no retry can ever clear, got one.Four lessons the fix's review surfaced, each with the concrete failure mode:
getPushPermission()is authoritative and already exposed.step.statereads were safe; making it reachable mid-flow turned each one into a latent bug. Two reviewers independently found two un-migrated reads — inert then, silent failures later.failedtoskippedwas right for the user and destroyed the ability to size the denial cohort. Restoring it cost ~6 lines; the durable half is Activation outcomes: a browser-blocked step is indistinguishable from a voluntary skip in the durable record #5617.innerHTMLgetter replays the assigned string will go vacuous. It is sound only while nothing mutates the subtree post-render — and this component already does that elsewhere (the brief step's preview swap, verified atProActivationInterstitial.ts:1055-1056onmain). Once coverage reaches there,doesNotMatchstarts passing because nothing was parsed rather than because the thing is absent: green while red.Also adds an Activation Step State entry to
CONCEPTS.md. The existingActivation Interstitialentry describes the flow but not the per-step state vocabulary, and specifically not the terminal-vs-retryable distinction that this bug turned on.Grounding
Every
file:linecitation was verified against mergedmain(8d225505f), not the local checkout — one had drifted and was corrected. Both bundled validators pass (frontmatter parser-safety; mechanical path/SHA/link claims), as do biome and markdownlint. Cross-checked specifically:step.stateread remains, insideeffectiveStateitself — the doc's "all reads go through it" claim holdsActivationStepOutcomestill has noblockedmember, which is both what makes a blocked step resolve asskippedand the premise of Activation outcomes: a browser-blocked step is indistinguishable from a voluntary skip in the durable record #5617An overlap check across
docs/solutions/scored Low — the closest neighbour isbilling-state-cancelled-but-paid-through-misclassified-as-lapsed.md, which is the same root-cause class running in the opposite direction (a state that merely sounded terminal treated as terminal). The two are cross-linked rather than merged.Post-Deploy Monitoring & Validation
No additional operational monitoring required — documentation only, no runtime surface.