You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
docs(redirects): three entries in apps/docs/redirects.mjs point at pages that do not exist — live URLs 308 into a 404 #8948
Found while working #8904 (retiring the Vercel and ObjectQL-migration pages). Pre-existing and unrelated to those two pages — not introduced by #8904's PR, and deliberately left untouched there to respect that card's scope ceiling.
The defect
Three entries in apps/docs/redirects.mjs have destinations with no page behind them. Each is a live URL that answers a permanent redirect (permanent: true, so 308) into a 404:
Source URL (still live)
Destination
Destination page
/docs/guides/solutions/role-based-interfaces
/docs/ui/role-based-interfaces
missing
/docs/guides/plugin-chatbot-integration
/docs/ai/chatbot-integration
missing
/docs/concepts/cloud-artifact-api
/docs/deployment/cloud-artifact-api
missing
Verified against the tree at a8189aef4 by resolving every destination the way Fumadocs routes it (/docs/x to content/docs/x.mdx, .md, or /index.mdx). 92 entries checked, these 3 fail; nothing else in the table is dead or chained.
Why nothing caught it
apps/docs/redirects.mjs is checked by no gate at all. Its only consumer is apps/docs/next.config.mjs; nothing in scripts/ or .github/workflows/ reads it. Check Documentation Links runs lychee --offline over content/**, root README.md and ARCHITECTURE.md — the redirect table is outside that surface, so a destination can rot indefinitely with CI fully green. This is the same blind spot #8904 was raised to handle for its own two pages.
Likely causes, for whoever picks this up
role-based-interfaces — content/docs/ui/audience-based-interfaces.mdx exists. The page looks renamed (consistent with the direction check:role-word enforces) without its redirect being updated. Re-pointing at /docs/ui/audience-based-interfaces is the probable fix.
chatbot-integration — no near-match under content/docs/ai/. Needs a judgement call on the successor (/docs/ai is the neutral default).
cloud-artifact-api — no near-match under content/docs/deployment/. Same judgement call (/docs/deployment).
The first is mechanical; the other two need a destination decision, so this is not a pure chore.
Suggested scope
Fix the three destinations, and consider whether the table deserves a gate — a dependency-free resolver over docsRedirects is roughly the 30-line script used to find this, and would close the blind spot permanently rather than one rotted entry at a time.
⚠️ Serialization note for triage: this edits apps/docs/redirects.mjs, which PR #8947 (for #8904) also edits. Schedule after that merges to avoid a conflict on the same file.
Triage: lands in apps/docs/redirects.mjs (plus, at the dev's option, a ~30-line resolver gate under scripts/ as the card suggests); rationale: concrete defect with a named landing spot — three dead redirect destinations, verified by the filer at a8189aef4. No maintainer decision required: the destination choice for the two no-near-match entries is in-PR discretion with the card's neutral defaults (/docs/ai, /docs/deployment). Routed domain:devx, type Bug, → pm:queue.
Serialization: the card's stated same-file conflict window with PR #8947 has passed — #8904 closed completed at 02:52Z and PR #8947 is closed. Claimant must still re-verify redirects.mjs against current main before dispatch (same-day churn on this file).
Dedup: redirect-rot queries return only this card.
{
"issue": 8948,
"status": "done",
"branch": "claude/issue-8948-dead-redirect-destinations",
"pr": "https://github.com/objectstack-ai/objectstack/pull/9015",
"premise_still_valid": true,
"summary": "All three premises re-verified on current main before editing: the full-table sweep at baseline reproduced the filer's a8189aef4 numbers exactly (92 entries, 3 dead, 0 chained). Branch taken per entry, with the search behind it: role-based-interfaces -> /docs/ui/audience-based-interfaces (SUCCESSOR branch: git records a content-identical R100 rename 02f6af43c, plus an earlier R091 from guides/solutions, so the redirect stopped one hop short); chatbot-integration -> /docs/ai and cloud-artifact-api -> /docs/deployment (SECTION-INDEX branch: both pages were deleted, not renamed, in one commit 97ad5702c 'remove cloud-only intro pages' which names each explicitly; searches over git history for '*chatbot*' / '*cloud-artifact*' / '*artifact-api*', a filename scan of the whole current content/docs tree, and a content grep all found no successor, and publish-and-preview DROPPED its cross-link rather than absorbing the content, so pointing there would assert a move that provably did not happen). Both fallbacks match the precedent already recorded in this file under the maintainer ruling of 2026-08-15: a retired page with no successor lands on the section index. No source entry was deleted. The gate was evaluated and NOT built here - filed as #9014.",
"tests": "All run in the worktree; union re-run after the final commit at 0b2d0f3ba (git rev-parse --short HEAD), working tree clean. (1) Full-table Fumadocs-resolution sweep (/docs/x -> content/docs/x.mdx | .md | x/index.mdx | x/index.md; bare /docs -> index.mdx; wildcard destinations -> target directory; chain matching per Next semantics where '/a/:path*' matches /a and /a/deep, first match wins): BASELINE on main = 'entries checked: 92, dead: 3, chained: 0' exit 1, naming exactly the card's three entries; AFTER on branch = 'entries checked: 92, dead: 0, chained: 0' exit 0. (2) Resolver proven capable of failing in both directions - dead detection showed a real red-to-green transition on the same script (3 -> 0), and chain detection, which never fires against the real table, got a positive control: one entry temporarily aimed at /docs/guides/skills (itself a source) produced 'DEAD/CHAIN ... [CHAIN -> matched by source /docs/guides/skills]', chained: 1, exit 1. Reverted from the commit, restore proven byte-identical (git hash-object = git rev-parse HEAD: = 62e2092c7, porcelain empty). (3) Consumer check: toNextRedirects() = 92 entries, 0 malformed, all permanent: true. (4) Gates - node scripts/pm/dispatch-gates.mjs apps/docs/redirects.mjs reports 'No check family names the given paths in its own source' across 98 discovered families (independently confirming the card's no-gate claim from the derivation side); pnpm check:nul-bytes OK (5947 files, 75 self-test assertions); npx eslint apps/docs/redirects.mjs clean; pnpm check:role-word OK (43 baselined files, no new occurrences) - not implicated by path since it scans only content/docs and skills .md/.mdx, run anyway because it is a ratchet family and the diff adds the words 'role-based' to a file. No ablation in this card, so no rebuild claim is made. Labels read back after bots settled: ['documentation', 'skip-changeset'] - skip-changeset was already present, so no write was issued and nothing could be clobbered.",
"open_questions": [],
"out_of_scope_findings": [
"filed as #9014: nothing verifies apps/docs/redirects.mjs destinations resolve - the table can rot with CI fully green (the gate the card asked me to evaluate; recommendation included, deliberately not shipped in this PR)"
]
}
Activity
os-project-manager commentedon Aug 16, 2026
Triage: lands in
apps/docs/redirects.mjs(plus, at the dev's option, a ~30-line resolver gate underscripts/as the card suggests); rationale: concrete defect with a named landing spot — three dead redirect destinations, verified by the filer ata8189aef4. No maintainer decision required: the destination choice for the two no-near-match entries is in-PR discretion with the card's neutral defaults (/docs/ai,/docs/deployment). Routeddomain:devx, typeBug, →pm:queue.Serialization: the card's stated same-file conflict window with PR #8947 has passed — #8904 closed completed at 02:52Z and PR #8947 is closed. Claimant must still re-verify
redirects.mjsagainst currentmainbefore dispatch (same-day churn on this file).Dedup: redirect-rot queries return only this card.
Size/model suggestion: S–M, sonnet.
Generated by Claude Code
os-project-manager commentedon Aug 16, 2026
Claiming this card.
session_011RB4waLuNbdruCo6X9oobmclaude/issue-8948-dead-redirect-destinationsStarting now; will re-verify the three destinations against current
mainbefore editing.Generated by Claude Code
Generated by Claude Code
os-project-manager commentedon Aug 16, 2026
{ "issue": 8948, "status": "done", "branch": "claude/issue-8948-dead-redirect-destinations", "pr": "https://github.com/objectstack-ai/objectstack/pull/9015", "premise_still_valid": true, "summary": "All three premises re-verified on current main before editing: the full-table sweep at baseline reproduced the filer's a8189aef4 numbers exactly (92 entries, 3 dead, 0 chained). Branch taken per entry, with the search behind it: role-based-interfaces -> /docs/ui/audience-based-interfaces (SUCCESSOR branch: git records a content-identical R100 rename 02f6af43c, plus an earlier R091 from guides/solutions, so the redirect stopped one hop short); chatbot-integration -> /docs/ai and cloud-artifact-api -> /docs/deployment (SECTION-INDEX branch: both pages were deleted, not renamed, in one commit 97ad5702c 'remove cloud-only intro pages' which names each explicitly; searches over git history for '*chatbot*' / '*cloud-artifact*' / '*artifact-api*', a filename scan of the whole current content/docs tree, and a content grep all found no successor, and publish-and-preview DROPPED its cross-link rather than absorbing the content, so pointing there would assert a move that provably did not happen). Both fallbacks match the precedent already recorded in this file under the maintainer ruling of 2026-08-15: a retired page with no successor lands on the section index. No source entry was deleted. The gate was evaluated and NOT built here - filed as #9014.", "tests": "All run in the worktree; union re-run after the final commit at 0b2d0f3ba (git rev-parse --short HEAD), working tree clean. (1) Full-table Fumadocs-resolution sweep (/docs/x -> content/docs/x.mdx | .md | x/index.mdx | x/index.md; bare /docs -> index.mdx; wildcard destinations -> target directory; chain matching per Next semantics where '/a/:path*' matches /a and /a/deep, first match wins): BASELINE on main = 'entries checked: 92, dead: 3, chained: 0' exit 1, naming exactly the card's three entries; AFTER on branch = 'entries checked: 92, dead: 0, chained: 0' exit 0. (2) Resolver proven capable of failing in both directions - dead detection showed a real red-to-green transition on the same script (3 -> 0), and chain detection, which never fires against the real table, got a positive control: one entry temporarily aimed at /docs/guides/skills (itself a source) produced 'DEAD/CHAIN ... [CHAIN -> matched by source /docs/guides/skills]', chained: 1, exit 1. Reverted from the commit, restore proven byte-identical (git hash-object = git rev-parse HEAD: = 62e2092c7, porcelain empty). (3) Consumer check: toNextRedirects() = 92 entries, 0 malformed, all permanent: true. (4) Gates - node scripts/pm/dispatch-gates.mjs apps/docs/redirects.mjs reports 'No check family names the given paths in its own source' across 98 discovered families (independently confirming the card's no-gate claim from the derivation side); pnpm check:nul-bytes OK (5947 files, 75 self-test assertions); npx eslint apps/docs/redirects.mjs clean; pnpm check:role-word OK (43 baselined files, no new occurrences) - not implicated by path since it scans only content/docs and skills .md/.mdx, run anyway because it is a ratchet family and the diff adds the words 'role-based' to a file. No ablation in this card, so no rebuild claim is made. Labels read back after bots settled: ['documentation', 'skip-changeset'] - skip-changeset was already present, so no write was issued and nothing could be clobbered.", "open_questions": [], "out_of_scope_findings": [ "filed as #9014: nothing verifies apps/docs/redirects.mjs destinations resolve - the table can rot with CI fully green (the gate the card asked me to evaluate; recommendation included, deliberately not shipped in this PR)" ] }Generated by Claude Code
Generated by Claude Code
fix(docs): three redirect destinations point at pages that do not exi…
ci(docs): gate that apps/docs/redirects.mjs destinations resolve (obj…