Merge the Mintlify import into main - #2494
Merged
Merged
Conversation
Deletes every .html.md, .html.markerb and .erb page, the partials tree, the Buildkite pipeline whose only job was triggering a marketing-site build, the old image tree, the generated flyctl command pages, Sitepress build artifacts, and the two unpublished drafts that the port carried across. Media moves with the content: the new pages reference /images and /videos, which arrive in the next commit. Keeps the Vale configuration and its style rules, the GitHub workflows, the README, the issue and PR templates and the license, all of which need editing rather than deleting.
748 pages as MDX, docs.json with navigation covering 744 of them, styles.css, images, videos and snippets, and the Machines API spec. public/fonts carries only Bricolage Grotesque and Fragment Mono. The four licensed Mackinac cuts are served from the private superfly/docs-fonts source, mounted at /assets, and styles.css points there. Two things still to change before this branch is connected as the base source: docs.json fonts.heading.source is the preview host and becomes docs.fly.io at cutover, and sourceRef still names Mintlify's own Sprites repo rather than superfly/sprites-docs.
Five content changes the 17 September zip predates: the Managed Postgres API link (9 Sep), the duplicated-words cleanup (11 Sep), the encrypted-snapshots note (12 Sep), the Hermes dashboard instructions (15 Sep) and the Ecto connection lifetime guidance (15 Sep). Ported by hand rather than copied, since the originals are Sitepress Markdown and these pages are now MDX. The Hermes page also drops a stray space in a bold run, and the MPG page drops a TODO that the same change resolved. Also gitignores the licensed Mackinac files so a stale zip cannot reintroduce them into a public repo. Still outstanding: the nav entry for the Managed Postgres API link, which lived in a Sitepress partial and now belongs in docs.json.
…-pager Both are needed before the repos are connected to Mintlify. The Sprites tab's sourceRef still named mintlify-onboarding/flyio-sprites-migration-preview, so the tab would have kept building from Mintlify's copy whichever repos we connected, and the deletions on the sprites-docs import branch would never have taken effect. /rails/one-pager came across as a flat 78 KB copy of 20 Rails pages that would have to be regenerated by hand. Mintlify offered to delete it and redirect to /rails, and said on 16 Sep that the redirect was already in the zips. It was not. Removes the page and its nav entry and adds the redirect.
postgres/getting-started/what-you-should-know.mdx is gone, with /postgres/getting-started/what-you-should-know/ redirecting to /postgres. That page carries the same framing: the unmanaged title, the Managed Postgres warning snippet, and the high availability versus single instance discussion. Eight prose links pointed at the removed page and are repointed. Two of them, in deep-dive/postgresql.mdx and js/prisma/postgres.mdx, asked for a list of recommended external providers that only existed on the removed page, and their anchor was already dead because the heading had been renamed. The first now says simply that you can host anywhere, the second points at Managed Postgres. The link on postgres/index.mdx is dropped rather than repointed, since that page is now the destination and its warning snippet already says the same thing. Seven further occurrences are left alone. They sit inside flyctl output that the docs quote verbatim, so the URL is what the tool prints rather than a link we wrote. The redirect covers them. One of those, at postgres/getting-started/create-pg-cluster.mdx:18, lost its code fence in the port and renders as body text. Worth fixing separately.
create-pg-cluster.mdx carried the tail of the fly postgres create output as body text. The port closed the code fence at the end of the shared pg-create snippet and left the last four lines outside it, so terminal output rendered as prose. Fenced in place. The same output is correctly fenced in the eight other pages that quote it, so this was the only one affected. js/prisma/postgres.mdx described Managed Postgres as an upcoming product with dates and pricing yet to be announced. It has shipped, and the line above it now points at /mpg, so the callout is removed rather than rewritten.
Mintlify's support confirms this is a docs.json setting rather than a dashboard toggle, which is why the robots meta seen on docs.fly.io this afternoon did not persist. It has to be in the branch before the repos are connected, otherwise the first build publishes all 850 pages crawlable and the noindex only arrives on the second. The window this closes is between connecting the repos and Wednesday's wildcard, when the full site is live at docs.fly.io while fly.io/docs is still canonical and nothing stops Google indexing both. There is no scheduled expiry. This must be removed on cutover day or the site launches deindexed.
The tab was generating from machines-api/openapi.json, committed on 21 August
and since drifted: the hosted document at docs.machines.dev/openapi.json carries
70 paths against the committed copy's 68, the two missing being
/v1/postgres/{postgres_cluster_id}/queries/active and /queries/slow.
Trevor confirmed on 21 September that the openapi field takes a URL as readily
as a path, and checked the hosted document himself for public reachability,
absence of auth and HTTPS. Verified again here before the change: 200, 70 paths,
both endpoints present.
The tradeoff is that the reference now refreshes whenever a build runs rather
than drifting silently, at the cost of depending on docs.machines.dev being
reachable at build time. The committed copy is left in place for now rather than
deleted, so reverting this is a one-line change.
superfly/landing#1253 added 78 redirects for dead URLs that Search Console still reports, 72 of them with /docs sources. Those stop working at cutover: the ui-ex wildcard for /docs/* sits in fly_redirects, which runs ahead of fly_proxy_old, so the request is answered before it ever reaches landing's nginx and the rule never fires. Ported here so the work survives Wednesday. The other six, outside /docs, are unaffected and stay where they are. 71 entries, since /mpg/configuration was already covered. Two adjustments to what landing does: Twenty would otherwise have become chains, where the target is itself a redirect here. /flyctl/wireguard-token/ to /flyctl/wireguard to /flyctl/cmd/fly_wireguard is three hops on top of the wildcard, so they point at the final target instead. Two were already stale. /reference/sprites/ and /sprites/getting-started/ send readers to docs.sprites.dev, which is right today and wrong on Wednesday, so both now go to /sprites. Destinations outside the docs, the GPU retirement post and the legal pages, are absolute fly.io URLs. Every target was checked against the live site. Additive only, no duplicate sources and no chains in the resulting table of 569.
Merged to main on 18 September, after the 17 September zip the import branch was built from, so it was absent from the MDX. Both shadow bucket commands were missing the required --shadow-name flag, so the documented examples would not run as written. The attribute count is now stated as five and they are named, and the bucket deletion paragraph says that deletion removes every object and that --yes skips the confirmation for automation.
Seventeen of the eighteen corrections, across blueprints, prisma, litefs, shopify, the flyctl volumes reference, the MCP transports and the extensions API. The eighteenth, a doubled parenthesis in a dashboard link on blueprints/staging-prod-isolation, was already correct in the MDX because the port normalized it. Four needed the word applying by hand rather than the whole line, since the port rewrote the links those lines carry.
Six corrections across the edgedb, nginx, minio and private DNS app guides, the postgres connection examples and the rails cookbook index. Two needed the word applying by hand rather than the whole line, since the port rewrote the links those lines carry.
One word on the billing page, account purposes to accounting purposes.
The SSE and streaming HTTP transport pages share this sentence, and #2480 only caught the streaming HTTP copy. Found while porting that commit across.
Adds the Client libraries section to the Machines API index. The page named the OpenAPI spec but no package, so a reader or an agent landing there could not tell that fly-go exists or that Sprites has SDKs. Ora's agent-readiness scan reports "no SDK packages found" for fly.io for that reason. Links follow the MDX conventions rather than the Sitepress ones: no /docs prefix, no +external suffix, and /sprites rather than /sprites/. Every link was rechecked here. All resolve. npmjs.com answers 403 to automated requests, so @fly/sprites was confirmed through the registry API instead. Alex's companion pull requests have since diverged: landing#1249 merged on 18 September, and ui-ex#5602, the ARD catalog, was closed without merging. Neither affects whether this page is correct.
As ported from #2490 the link went to https://sprites.dev/mcp, which answers 401 because it is an MCP endpoint to configure in a client rather than a page to open. A reader following a link labelled "an MCP server" got an auth error. It now points at /sprites/integrations/remote-mcp, the Sprites remote MCP page, which came across from sprites-docs and serves 200. The endpoint stays discoverable through that page.
The README on this branch still said "flyio-migration-preview", the name of Mintlify's onboarding repository, which came across in the port. It now names the repository, states that the format changed on 23 September, and lists the four differences a contributor actually hits: MDX rather than Sitepress, navigation in docs.json, internal links without the /docs prefix, and redirects in docs.json. This repository is public and has over a thousand forks, all of them on the old shape, so the first thing an outside contributor meets after cutover is a tree that does not match their branch. The contributing guide is still unwritten and unowned; this is the short version that stops the repository being silent about it.
Reverts 3bbff69. Pointing the tab at docs.machines.dev/openapi.json did not take: nine builds later the site was still generating from the committed file. The hosted document has 24 operations tagged Postgres Clusters, the committed copy had 22, and the built site had 22, with /api/machines/postgres-clusters/list-slow-queries returning 404. The syntax was not the problem. Mintlify's own documentation shows the object form taking a URL in source, the document is public and HTTPS, and Trevor fetched it himself on 21 September. Asked them why it is not being read; the likely answer is caching, and nothing in their docs says what invalidates it. So the committed copy is the source again, refreshed from the hosted document today. It gains exactly the two Postgres query paths and loses nothing, checked before overwriting. That puts all 70 paths on the site tomorrow through a mechanism we control, rather than shipping two known-missing endpoints while waiting on an explanation. The drift this was meant to solve returns, and is now on the post-cutover list rather than solved.
#2492 merged to main at 19:09 UTC today, generated and self-merged by the flyctl docs syncer. That is the workflow flyctl#5223 pauses, and it ran during the freeze without anyone knowing, which is the argument for pausing it in one commit. Three pages, carried into MDX so they are not lost when the import branch merges and so main does not end up holding a Sitepress page beside its MDX equivalent: fly_tokens_revoke_supplied new, documents `fly tokens revoke supplied` fly_auth_logout gains the --force flag fly_tokens_revoke lists its new subcommand The new page also needed two things the bot's output cannot provide: a nav entry, so fly_tokens_revoke becomes a group carrying it rather than a leaf, and a redirect from the old site URL, matching how every other flyctl page is handled. This documents flyctl#5208, the change behind #2491, which is being held because the feature was not in a release. The bot generating these pages means it now is, so that pull request is probably unblocked.
NullHypothesis opened #2491 on 22 September against the Sitepress tree. It was held because it documents fly tokens revoke supplied, which was merged in flyctl#5208 but not released, and shipping documentation for a command that does not run is worse than shipping it late. It released today. v0.4.106 went out at 19:14 UTC naming #5208, revoke_supplied.go exists at that tag, and the docs syncer generated the reference pages for it, which is how this surfaced. Three changes, all his: FLY_ACCESS_TOKEN takes precedence when both variables are set, where the page said only that either would work. fly auth logout now revokes as well as removes the saved token, and does neither to tokens supplied through the environment. The page described the old behavior. fly tokens revoke supplied is documented, with the precedence order and the two-step dance needed when both environment variables are set. The generated reference already covers the flags. This is the half that explains when to reach for it, which is the part readers need and the part a generator cannot produce.
Trevor diagnosed the Machines API problem and it was not what any of us thought. The tab hand-lists every operation as a METHOD /path entry, and when a navigation element carries both openapi and pages, Mintlify generates only what is listed. So the hosted spec was being fetched all along and rendered the same 98 listed operations, which is why the output looked identical to the committed file. The two Postgres query endpoints were never going to appear from either source. Adds them to the list, which is the minimal fix and works against either source. The list now carries 100 operations. Separately, PUT and PATCH on the machine metadata path shared both a summary and an operationId. Mintlify slugs from the summary, so the two collided and one page was unreachable; a duplicate operationId is also invalid OpenAPI. PATCH now has its own, worded so it distinguishes the two without claiming a behavioural difference the spec does not describe. That bug is upstream at docs.machines.dev and this patch is local, so it will be lost the next time the copy is refreshed. Worth reporting to whoever publishes that document. The larger fix, dropping the hand-listed endpoints so the tab auto-generates, is on the post-cutover list. It loses the per-group icons and the curated order, so it is not a change to make the evening before a domain move.
…d copy The metadata collision is already fixed at the source and the published document is behind it. In superfly/api spec/swagger.json, PUT on the machine metadata path is Machines_update_metadata_deprecated, marked deprecated, with its own summary saying it is a deprecated alias of PATCH. The copy served from docs.machines.dev still has both methods sharing an operationId and a summary. So dd169a3 patched the wrong side. It invented a summary for PATCH when the real fix renames PUT and deprecates it, which also tells a reader something useful that my version threw away. The two documents are otherwise identical: same 70 paths, same 100 operations, and these two the only operations differing in summary or operationId. So this replaces ours with the repository copy wholesale rather than hand-patching. Reported separately, since anyone generating a client from docs.machines.dev is working from the older document.
The client libraries section told readers to generate a client from docs.machines.dev/openapi.json. It now names docs.fly.io/machines-api/openapi.json, the committed copy this site builds the reference from, which is already served as a static file. Lillian suggested it in #fly-machines and it is better than what it replaces. Readers generate from the same document they are reading, so the two cannot disagree, and the Machines team has one file to keep current rather than two. Line 22 is untouched. That link points at the reference tab rather than the file, which is a different thing doing a different job.
d15a805 replaced this file with superfly/api spec/swagger.json, which is Swagger 2.0. Mintlify's openapi field takes OpenAPI 3, so every build since 21:56 UTC yesterday has failed on "Failed to fetch OpenAPI file for anchor or tab", and nothing pushed after that time has reached the site. Kyle flagged the Sprites Integrations pages as missing this morning, which is this: they are in the repository and the site has not rebuilt. Re-fetched from docs.machines.dev, which is the OpenAPI 3 conversion and which picked up the metadata deprecation at 21:43 yesterday. So this keeps the fix d15a805 was reaching for and drops the format that broke the build. The two documents were compared last night and the format difference was seen and not acted on. Checking that a spec change still builds is now the obvious thing to do after touching one.
Mintlify writes no check runs and no commit statuses, so a failed build leaves no trace in GitHub at all. A bad spec broke every build from 21:56 UTC on 22 Sep and went unnoticed for seventeen hours. This watches the deployment id that docs.fly.io serves in its x-version header and fails if it has not changed twenty minutes after a push, which puts a red mark on the commit that caused it. docs.fly.io is a single deployment built from superfly/docs, superfly/sprites-docs and superfly/docs-fonts together, so the same check runs in both content repositories. The six Integrations pages pushed to superfly/sprites-docs at 23:30 UTC stayed dark until the spec in superfly/docs was fixed the next afternoon.
fonts.heading.source still pointed at flyio-migration-preview.mintlify.site, which would have made a domain we do not control a hard dependency of the production site. The custom domain is attached and https://docs.fly.io/assets/fonts/mackinac-bold.woff2 returns 200 as font/woff2 at 26,456 bytes, so the swap is safe now. This was recorded in repo-cleanup-after-zip.md as a cutover-day edit but had not reached the cutover sequence or the run sheet. It would not have been caught by the checks there either, because both URLs serve the font today, so the verification passes either way. There is no safe default to fall back on. Mintlify rewrites a relative path to their S3 bucket, which 503s, and omitting the field falls back to Google Fonts, which does not carry this face. The four @font-face rules in styles.css are relative and need no change.
machines/guides-examples/machines-app-using-flyctl references /images/testrun-err-empty-response.webp and /images/testrun-hello.webp, and neither file was in the repository. Sitepress kept images beside the page they belong to, at machines/guides-examples/images/, and 592c57e removed that tree with the rest of the Sitepress sources. The Mintlify content from the 17 September zip flattened the references to /images/ without carrying the files. Restored from 592c57e^ at the flattened path the pages now expect. Worth noting these are broken on the live Sitepress site as well: it serves them from /images/images/, which 404s today. So this fixes something that was already wrong rather than preventing a regression. Audited all 162 local image references in this repository. These two were the only ones missing.
The workflow watched the x-version header on docs.fly.io and failed when it did not change within twenty minutes of a push. That was built on an assumption I never verified, that x-version changes when our content rebuilds. It does not. The Mintlify Activity tab shows five successful builds after 16:35 UTC today, covering every push from this afternoon, while x-version stayed at dpl_WUrXqCd5nPFDSzoTYvx4Wt8NzcVY throughout. So the header tracks something else, and every failure the check produced today was a false alarm. Two of those false alarms were read as evidence that Mintlify skips rebuilds for tooling and asset pushes. That conclusion is withdrawn with the check. Removing it before cutover rather than after. Step 4d is a docs.json push and would have gone red for this reason, which is the worst place for a false alarm: 4d is already the step that fails silently, so a red mark there would be indistinguishable from a real problem. What prompted the check is unchanged. Mintlify writes no check runs and no commit statuses, and Sophia confirmed on 23 Sep that there is no failed-build alert. A replacement has to assert that a specific change reached the live page, because a failed build leaves the previous good site serving and looks healthy from outside.
Their collector is live on docs.fly.io and writes a persistent anonymous ID to localStorage plus a session ID to sessionStorage. No cookies, but a localStorage identifier is treated the same way under ePrivacy, and analytics is not strictly necessary, so it needs consent. We cannot gate it. Mintlify recognize OneTrust, Osano and Transcend natively and our banner is homegrown, so there is nothing for them to read. Disabling is the only lever, and Dean confirmed on 21 Aug that with this key the SDK never initializes and neither identifier is created. Matt called it in #security on 23 Sep: "I think we have to disable the analytics, then". The consequence is that docs.fly.io has no analytics at all until our own consent-gated script is ported, which is on the post-cutover list and is larger than earlier notes assumed. This is the reversible direction. Turning it back on costs one commit; data gathered without consent cannot be ungathered.
Kyle crawled fly.io/docs rather than docs.fly.io, so most of his fifteen internal findings are Sitepress artifacts that no longer exist. Four survived the conversion into MDX. Two of those have unambiguous targets. laravel-redis pointed "above" at /laravel/the-basics/databases#setup-using-the-fly-io-redis-docker-image, a page that no longer exists. The word "above" and the anchor name both describe the section on this same page, "Fly.io Redis Docker Image", so it becomes an in-page anchor. Confirmed against the rendered page rather than guessed: the live id is fly-io-redis-docker-image. deep-dive/phoenix had [Ecto.Adapters.Postgres](Ecto.Adapters.Postgres), which was never a link, just the module name in both halves. Points at hexdocs now. The other two need a judgment call and are not included. reference/content- encoding links to /apps/performance, which 404s on the old site as well, so it has been dead a while and machines/cpu-performance is about vCPU types rather than troubleshooting. machines/runtime-environment links to a dashboard route that needs someone logged in to verify.
machines/runtime-environment pointed at https://fly.io/dashboard/personal/machines. That route does not exist and never did: ui-ex has no machines route under /dashboard/:organization_id, the bare /machines is the marketing page, and Machines are viewed per app at /apps/:app_id/machines/:machine_id. The correct URL needs an app name, so there is nothing generic to link to. The sentence now describes where to look and keeps the fly machine status reference. reference/content-encoding linked to /apps/performance from its "More in the docs" list. No file ever existed at that path: the link was born broken in 6244c83, the commit that added the page, so it has never worked on any site. Retargeted to /apps/fine-tune-apps, which is live and is about gathering data to optimize an app. The link text changes with it, since the old wording described a page that never existed. That closes all fifteen of the internal findings. Five were fixed by the migration, six no longer exist in the content, and four are now handled.
Both halves of the documentation are in Plausible today and both stop on Wednesday. fly.io/docs is covered because landing puts <script defer data-domain="fly.io" src="/js/events.js"> on every page it serves, proxied first-party through fly_proxy_plausible in ui-ex's endpoint. docs.sprites.dev is covered by a direct plausible.io script in the Astro site's Head component. Neither survives the move: landing stops serving the docs, and the Astro components are already gone from the import branch. Matt approved in #security on 23 Sep. Alex wants Plausible now with PostHog and GA4 to follow next week, which is the right order: Plausible needs no consent gate, so it does not wait on the ui-ex CORS change the others need. Hosted rather than pointed at our own proxy. Mintlify's server key builds /js/script.js and our proxy serves /js/events.js, so it would need an alias plus CORS on /api/event for a cross-origin POST, both changes in another team's repository. docs.sprites.dev already loads the third-party script today, so this is not a new posture for the documentation. A new docs.fly.io site rather than writing into fly.io. The /docs path prefix disappears at cutover, so existing filters on it stop matching new data whichever site receives it. A separate site makes that break visible rather than quietly mixing documentation paths into marketing ones. Set only here, not in sprites-docs. One deployment serves both sources, and setting it twice risks counting /sprites pages twice. The site does not exist yet. Kristin asked Matt to create it at 13:41 PDT. Until he does, Plausible drops the events, nothing errors, and pageviews in that window are lost rather than buffered.
This run crawled docs.fly.io rather than fly.io/docs, so unlike the first one everything in it is about the site we are shipping. Six were Markdown reference-style definitions carrying the old /docs prefix, [label]: /docs/litefs/config#lease-management and similar, across four litefs pages. My earlier check reported none of these because it matched inline links only, which is the same mistake in a different shape: a pattern that was too narrow, reported as an absence. One more was in the committed Machines API spec, a root-relative /docs/reference/openid-connect/ that reaches generated pages through the operation description. Pointed at /security/openid-connect, which is where the redirect lands anyway. The other eight /docs paths in that spec are absolute fly.io URLs, so they survive on the wildcard and belong to the post-cutover sweep rather than here. The rest: seven rust framework pages linked to rust-templates/tree/ with the path variable never filled in; shared-nothing had a URL broken across a line break, ht + newline + tp://; smokescreen pointed at /reference/wireguard, which no longer exists; mpg carried a Sitepress link-template artifact, docs.machines.dev/+external; puppeteer linked to /speedrun and to a yt-views file that was never migrated; and apps-resource linked to fly.io/reference/services rather than our own page. Not included: sixteen links to raw DockerfileN files in the Rails cookbooks. Those files existed under Sitepress and were removed with it. Restoring them needs a decision about whether they become static files or inline code blocks, which is content work rather than a link fix.
Five cookbook pages linked to raw DockerfileN files beside them. Those files are still in the repository and always were, but Mintlify does not serve a file with no extension, so all sixteen links 404. /machines-api/openapi.json serves fine, which is how we know the rule is the extension rather than the file. Measured what each file adds before deciding, rather than moving all sixteen by hand. Eleven are already on their page in full, so the link was a duplicate of code the reader has just scrolled past and the section is simply gone. Two on the node page and all three on the sources page are different. node Dockerfile5 and Dockerfile6 each carry twelve lines the page never shows, whole build stages installing Ruby through rbenv and rvm on a node base. The three sources files are only about thirty percent on the page and the complete version existed nowhere else. Those five are now CodeGroups, verbatim from the files. The files themselves stay. They are not served, so they cannot 404, and they are the source the blocks were taken from. Removing them is tidying that can wait.
This branch was successfully deployed
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.
Moves
mainfrom Sitepress to the Mintlify content, 34 commits.sitepress-finalmarksmainas it stands immediately before this, at1976805b.The merge button is disabled, and that is expected
GitHub reports ten conflicts. None of them is a real disagreement.
maincarries five commits the import branch does not, all from the code freeze:mainmintlify-importasb8f9898ftigris shadow-bucket and delete examples (#2469)af9050616caa9048typos in prisma, extensions API, mcp, blueprints (#2480)f14985e71ee90e56typos in app-guides, rails cookbook, postgres (#2481)e898501bf638327ftypo in billing (#2479)434902191976805bflyctl bot self-merge during the freeze (#2492)1a870b14Every one was carried across by hand, so the content is already here in MDX form.
The conflicts come from git's rename detection. It pairs each
.html.markerbedited onmainwith its converted.mdxon this branch, treats that as a rename, and cannot merge a Sitepress edit into a converted file. Eight conflicts of that shape, plus two modify/delete on files this branch removed.How it is being merged
Not with the button. Merge commits are disabled on this repository, so the button would squash 34 commits into one, and GitHub's web conflict editor cannot resolve modify/delete conflicts in any case.
Instead a merge commit is built locally with the tree resolved to this branch in full, then pushed to
main. GitHub will mark this pull request merged once its head commit is reachable frommain.The resulting tree was verified against this branch before anything was pushed:
Both parents are kept, so the Sitepress history stays reachable by ancestry.
If it needs undoing
The tag is the first parent of the merge, so that restores
mainexactly. Nothing points atdocs.fly.iountil the edge wildcard in superfly/ui-ex#5654 merges, which is the last step of the cutover, so a problem here is not visible to readers.