Repository navigation
docs(deployment): retire the Vercel and ObjectQL-migration pages — delete, re-point their inbound redirects, and fix the prose links into them #8904
Description
Card 01 of the deployment-section restructure (maintainer ruling, 2026-08-15). Two pages come out of content/docs/deployment/. They are one card, not two — both edit content/docs/deployment/meta.json and apps/docs/redirects.mjs, so splitting them only serialises the same two files across two PRs.
Rulings (settled — do not re-litigate)
- 「
https://objectstack.ai/docs/deployment/vercel已经不需要了。平台通常用 docker 发布。」 → deletevercel.mdx, redirect toself-hosting. - 「
migration-from-objectql作废」 → deletemigration-from-objectql.mdx.
Why these two, measured
vercel.mdx (195 lines) documents a path no CI covers — vercel does not appear anywhere in .github/workflows. (The "Vercel Preview Comments" check on PRs is the docs site's own hosting, unrelated to deploying a user app.) Meanwhile Docker is the real shipping path: docker/Dockerfile plus .github/workflows/docker-publish.yml. The page is also already visibly decaying — it carries a Removed in 11 callout for the MSW mode and the Next.js adapter.
migration-from-objectql.mdx (179 lines) documents a one-time @objectql/core → @objectstack/objectql port. It belongs to neither the platform-runtime nor the metadata-app lifecycle the section is being restructured around, and every published page is a standing maintenance obligation.
⚠️ The trap: both pages are already redirect TARGETS
apps/docs/redirects.mjs currently ends two older URLs at these very pages:
['/docs/guides/deployment-vercel', '/docs/deployment/vercel'], // line 95
['/docs/guides/objectql-migration', '/docs/deployment/migration-from-objectql'], // line 101Deleting the destinations without touching these leaves two live URLs redirecting into a 404. Next.js serves one redirect hop — it does not follow chains — so adding a second entry does not rescue them. Both existing entries must be re-pointed at the final destination, not merely supplemented.
Prose links that must be fixed in the same PR
content/docs/deployment/self-hosting.mdx links to the Vercel page twice:
- line 11 —
[Vercel guide](/docs/deployment/vercel) and assumes you have read … - line 424 —
- [Deploy to Vercel](/docs/deployment/vercel) — the serverless alternative
Line 424 is a Related-links entry (delete it). Line 11 is mid-sentence and needs the sentence rewritten, not just the link stripped. migration-from-objectql has no prose inbound links — only meta.json and the redirect above.
The Check Documentation Links gate (lint.yml) will catch a missed one, but do not use it as the search: find them first, then let the gate confirm.
Scope
- Delete
content/docs/deployment/vercel.mdxandcontent/docs/deployment/migration-from-objectql.mdx. - Drop both entries from
content/docs/deployment/meta.json. - In
apps/docs/redirects.mjs: re-point the two existing entries, and add/docs/deployment/vercel→/docs/deployment/self-hosting. Choose themigration-from-objectqldestination and argue it in the PR —/docs/deploymentis the neutral default; there is no successor page. - Respect the file's own documented ordering rule: "Exact entries come first; wildcard catch-alls for retired sections must stay last (first match wins)."
Docs-only, skip-changeset. Do not touch any other deployment page — the restructure that moves them is a later card.
Verify
git grep -rn "deployment/vercel\|migration-from-objectql" -- content/ apps/ # expect: only redirects.mjs
pnpm check:docs-audit-scope && pnpm check:release-notes && pnpm check:role-wordThen confirm both retired URLs and both older /docs/guides/* URLs each resolve in one hop to a page that exists.
Context
Full IA proposal and the other four cards: this is card 01 of 5, sequenced first because it is the cheapest irreversible move and nothing else depends on it. Cards 02–05 (new Upgrading page, publish-and-preview rewrite, Docker promotion in self-hosting, index rewrite) follow separately.
Activity
os-zhuang commentedon Aug 16, 2026
Claim: PM loop round 2
Session:
session_013gLCsJ1sDoJZZruDKMsHH3Branch:
claude/issue-8904-retire-vercel-objectql-docsWorktree:
objectstack-issue-8904Domain:
domain:devxFile surface:
content/docs/deployment/vercel.mdx(delete),content/docs/deployment/migration-from-objectql.mdx(delete),content/docs/deployment/meta.json,content/docs/deployment/self-hosting.mdx,apps/docs/redirects.mjs(stop on breach; explain in the report)Container & model:
S but not mechanical,mode:subagent,model: opusSerial constraints cleared: no open PR touches
content/docs/deployment/**orapps/docs/redirects.mjs. #8911 is the only other card onself-hosting.mdxand ispm:blockedbehind this one — it must not start until this merges.Model tier raised from the initially proposed
sonnettoopus, measured. The gate farm does not cover this card's hardest part:Check Documentation Linksrunslychee --offlineover content files, and nothing inscripts/or.github/workflows/referencesredirectsat all. So the two prose links inself-hosting.mdxare gate-caught, but the two dangling redirect entries are not — a wrong answer there ships two silently-404ing live URLs with CI fully green. Judgement outside the gate farm takes the higher tier.Routed under the maintainer's direct-dispatch channel. Authorizing instruction, verbatim: 「你先派 8904」
Generated by Claude Code
os-zhuang commentedon Aug 16, 2026
Claim amendment — declared file surface (session
session_013gLCsJ1sDoJZZruDKMsHH3, branchclaude/issue-8904-retire-vercel-objectql-docs).Three files beyond the surface declared in my claim above are touched by PR #8947. Amending the declaration so it still serializes correctly against parallel work:
.claude/workflows/docs-accuracy-audit.jscheck:docs-audit-scope— a gate this card names — fails on exactly that. Regenerated with the script's own--writeremedy.scripts/role-word-baseline.jsonmigration-from-objectql.mdxwas baselined at 2 occurrences;check:role-word— also named by this card — fails when a baselined file vanishes. Ratcheted down with the remedy the gate prints.packages/objectql/README.mdThe first two are mechanically forced by the deletion and add no gate surface — they are the two named gates. The third is the bounded in-place exemption: same defect class, mechanical form pinned by the sibling fix in
self-hosting.mdx, no other claim on the file (no open PR touches it), and no new verification surface. All three are named with their evidence in the PR body.Anyone claiming work on these three files should treat them as held until #8947 merges.
Generated by Claude Code
Generated by Claude Code
os-zhuang commentedon Aug 16, 2026
{ "issue": 8904, "status": "done", "branch": "claude/issue-8904-retire-vercel-objectql-docs", "pr": "https://github.com/objectstack-ai/objectstack/pull/8947", "premise_still_valid": true, "summary": "Both pages deleted, dropped from deployment/meta.json, and their inbound URLs re-pointed in apps/docs/redirects.mjs (two existing entries re-pointed, two new exact entries added before the wildcards per the file's ordering rule). The two Vercel prose links in self-hosting.mdx are gone — line 424 deleted outright, line 11's sentence rewritten. migration-from-objectql lands on /docs/deployment: /docs/protocol/objectql/ was weighed and rejected because those pages specify the ObjectQL protocol, not a package port, so they promise a successor that does not exist. THREE PREMISE CORRECTIONS. (1) The 'zero prose links to migration-from-objectql' claim is wrong: packages/objectql/README.md:100 linked into it by relative path. The PM sweep was scoped to content/ apps/; a repo-wide grep finds it, and it sits outside lychee's scan surface (content/**, root README.md, ARCHITECTURE.md), so nothing would have caught it — fixed here under the bounded in-place exemption. (2) Two gate-owned artifacts are mechanically broken by the deletion and were NOT in the scope ceiling: .claude/workflows/docs-accuracy-audit.js (check:docs-audit-scope fails on the 2 stale paths) and scripts/role-word-baseline.json (check:role-word fails when a baselined file vanishes). Both regenerated with the remedy each gate itself prints; both are named gates on this card, so this adds no new gate surface. (3) The Next.js one-hop mechanism is half right — see tests. Claim file surface amended in a comment above.", "tests": "No build or test run — docs-only change, no package source touched, so the shared heavy-verify lock was never needed. All gates run FROM THE FINAL COMMIT a34b9e8df. PM-named four: check:docs-audit-scope OK ('scope is in sync with content/docs/: 177 hand-written doc(s)'); check:release-notes OK ('every released major has a curated, navigable release page'); check:role-word OK ('43 baselined file(s), no new occurrences'); check:nul-bytes OK ('scanned 5932 text file(s) ... no raw ASCII control bytes'). Re-derived with `node scripts/pm/dispatch-gates.mjs` against the real diff, which ADDED four families the prompt did not name: check:doc-authoring OK ('375 files clean'), check:skill-frame-sync OK ('12 cases pass', 4 frame copies isomorphic), check-engine-split-ratio OK (matched only via the packages/objectql/README.md edit), and check:doc-formula-expressions — NOT RUN, the one family needing a workspace install. Skipping it is evidence-backed, not assumed: a repo-wide grep shows no baseline or fixture under packages/ names either deleted page, so it cannot be keyed on them, and a docs deletion only shrinks its input. BEFORE regenerating I ran both stale-artifact gates and watched them go RED with the exact expected messages ('2 listed path(s) do not exist'; 'baselined file is clean/gone (was 2) — ratchet DOWN'), then confirmed each regeneration diff was exactly one removed line per file — important for check-role-word --update, which rewrites the WHOLE baseline from the tree and could silently re-baseline other files; it did not. THE DELIVERABLE CI CANNOT GIVE: I resolved every one of the 92 redirect destinations against the tree the way Fumadocs routes them (/docs/x to content/docs/x.mdx|.md|/index.mdx). All four owned URLs resolve in exactly ONE hop to a real page: /docs/deployment/vercel and /docs/guides/deployment-vercel to self-hosting.mdx; /docs/deployment/migration-from-objectql and /docs/guides/objectql-migration to deployment/index.mdx. Zero entries in the table now chain (a destination that is itself a source) — checked explicitly. MECHANISM CORRECTION: the prompt's claim that supplementing without re-pointing 'does not rescue' the old URLs is half right. next.config.mjs is a plain redirects() via toNextRedirects() with no chain resolution, and middleware.ts is i18n-only and never touches these paths, so Next does match the table once per request — correct. But the response is a 308 whose Location an HTTP client re-requests, and that new request re-enters the table, so supplementing alone would have produced a TWO-HOP CHAIN, not a 404. The conclusion is unchanged (re-pointing is what the ruling asks and what I did, and one hop is strictly better), but the failure mode is a wasted round trip and diluted redirect signal, not a break. PM sweep otherwise confirmed: exactly two prose links to the Vercel page, both in self-hosting.mdx, nothing beyond them; the only surviving mentions of either page anywhere in the tree are the four intentional redirect entries and two archival lines in docs/audits/2026-06-handwritten-docs-accuracy-followups.md, which are a dated historical record of a June 2026 state and were deliberately left alone.", "open_questions": [], "out_of_scope_findings": [ "filed as #8948: three entries in apps/docs/redirects.mjs point at pages that do not exist — /docs/guides/solutions/role-based-interfaces, /docs/guides/plugin-chatbot-integration and /docs/concepts/cloud-artifact-api each 308 into a 404. Pre-existing, unrelated to the two retired pages, found by the same 92-entry resolver; ui/audience-based-interfaces.mdx exists, so the first looks like a rename whose redirect was never updated. Unassigned and unlabeled for triage; flagged there that it edits the same file as #8947 and should be scheduled after it merges." ] }Label read-back on #8947 (after bots settled):
size/m,skip-changeset— written as a union so the bot'ssize/msurvived the whole-set PUT.Generated by Claude Code
Generated by Claude Code
os-zhuang commentedon Aug 16, 2026
ACCEPT — PR #8947. Reviewed against the tree, not the report. Both corrections to my dispatch are upheld.
Where I was wrong — twice
1. "Zero prose links to
migration-from-objectql" was false.packages/objectql/README.mdlinked into it by relative path (../../content/docs/deployment/migration-from-objectql.mdx). My sweep was scoped tocontent/ apps/and I reported its result as if it were repo-wide.The part that makes this worth recording: I verified the link-checker's scan surface, and it is
content/**/*.md,content/**/*.mdx, rootREADME.mdandARCHITECTURE.md.packages/**/README.mdis outside it. So this would have merged green and left a dangling relative link — my narrow sweep was the only thing standing between that and production, and it was narrow. Finding it required ignoring the file list I supplied.2. My redirect mechanism was half wrong. I wrote that supplementing without re-pointing "does not rescue" the old URLs, implying a 404. The correction is right: Next matches the table once per request (that half of my claim holds), but the 308's
Locationis re-requested by the client and that request re-enters the table — so supplementing alone yields a two-hop chain, not a break. The remedy is unchanged and the PR does the right thing; my stated failure mode was wrong, and a card that had trusted my wording would have hunted the wrong symptom.Verified independently
.claude/workflows/docs-accuracy-audit.js— diff is exactly the two stale paths removed, zero additions.scripts/role-word-baseline.json— exactly one entry removed, nothing else re-baselined.On
--update, which deserves saying plainly, because it looks like gate-weakening at a glance: the script marks that flag⛔ MAINTAINER-ONLYfor the expand path — accommodating a new occurrence. The ratchet-down path is a different act, documented in the same header as the normal remedy: "a baselined file's count DECREASED / file vanished (improvement!) — run with--updateto ratchet the baseline down and commit it." The file here was deleted, so down was the only direction available, and the diff confirms the baseline only shrank. No maintainer-only action was taken. Checking the whole-file rewrite for silent re-baselining of unrelated files was exactly the right paranoia.Landing path
Path surface:
content/docs/**,apps/docs/redirects.mjs,scripts/role-word-baseline.json,packages/objectql/README.md,.claude/workflows/docs-accuracy-audit.js. The ACCEPT fork triggers ondocs/adr/**,.claude/skills/**andskills/**—.claude/workflows/is none of those, so this lands through the merge queue normally rather than waiting on a human. Recording that as a decision rather than leaving it silent, since the path shares a prefix with a fork trigger.CI is still converging (
ESLint,TypeScript Type Check,Test CoreandDogfoodshardsin_progress) — honest reading at report time. Holding the ready-flip until thelint.ymljob reportscompleted: success.Out-of-scope finding, spot-verified
#8948 is real. I confirmed two of its three:
content/docs/deployment/cloud-artifact-api.mdxandcontent/docs/guides/solutions/role-based-interfaces.mdxdo not exist, whilecontent/docs/ui/audience-based-interfaces.mdxdoes — consistent with the rename theory. It editsapps/docs/redirects.mjs, the same file as this PR, so it is correctly flagged to be scheduled after this merges.Downstream
#8911 (Docker promotion in
self-hosting.mdx) is blocked on this and must re-read the file on the merged ref —self-hosting.mdxline numbers moved here.Generated by Claude Code
os-zhuang commentedon Aug 16, 2026
Landed. PR #8947 merged.
Verified on
origin/mainas a second reading — "merged" and "the content is correct" are separate facts:content/docs/deployment/vercel.mdxandmigration-from-objectql.mdx— both gone.content/docs/deployment/meta.json— down to 11 pages, neither entry present.content/ apps/ packages/returns only the two intentional redirect entries (redirects.mjs:110-111). The two/docs/guides/*entries no longer match because they were re-pointed away from the deleted pages, which is exactly the outcome this card existed to secure.PR subscription released on merge. #8911 unblocked —
pm:blockedremoved, back topm:queue.Follow-up still open: #8948 (three pre-existing redirect destinations that do not exist). It edits
apps/docs/redirects.mjs, which this PR also touched, so it is now clear to schedule.Generated by Claude Code
docs(deployment): retire the Vercel and ObjectQL-migration pages (obj…