Skip to content

docs: prod FernDesk IA refactor (no public staging) - #20

Draft
echobt wants to merge 4 commits into
mainfrom
droid/2a5c5e50-docs-ferndesk-prod-refactor
Draft

echobt wants to merge 4 commits into
mainfrom
droid/2a5c5e50-docs-ferndesk-prod-refactor

Conversation

@echobt

@echobt echobt commented Sep 15, 2026

Copy link
Copy Markdown
Contributor

What this changes

Restructures docs.cortex.foundation around the products that actually exist, removes every public staging entry point, and makes the FernDesk sync production-only.

The live site was serving a staging mirror at /staging/*, a Design vertical in the nav and footer, and duplicate hub pages under hashed slugs (/chat-8hul5 beside /chat-5ywlo, nine index-* articles). Home was a generic help-center landing ("How can we help"). All four are addressed here.

Public IA

docs.json now reads as a platform docs site:

Get started | Chat | Code | Bot | CLI | API | Changelog

with Home ordered Get started → Build by product → API reference → Operate, replacing the help-center landing.

  • Design is no longer a product vertical. The tab, footer entry, home card, banner, icon/doodle/card assets, and the five pages linking to it are gone. Its one durable idea — a document panel beside a conversation — is Chat's canvas, which stays documented at /chat/canvases.
  • Duplicates folded into canonical pages: chat|code|bot|design/overview → the product index, chat/streamingchat/how-it-works, code/cli → the CLI tab, platformapi/overview, getting-started/desktopgetting-started/downloads.
  • 87 MDX pages, 87 nav entries, zero orphans, and a redirects entry for every removed path. An internal-link audit reports 0 broken links.

No public staging

  • Staging pages, nav, redirects, and copy removed. FERNDESK_TARGET must be production; anything else exits 2 before a single API call. The workflow no longer offers a staging choice.
  • check-docs-site.mjs now fails on staging in navigation, redirects, or page copy, with three new cases in check-docs-site.test.sh holding the line.

FernDesk sync correctness (root cause of the noisy slugs)

FernDesk rewrites a slug it considers taken — a create for chat is stored as chat-8hul5. The sync resolved identity by slug, so a run that lost its cache scanned the section, saw no chat, and created the page again under a fresh hash. That is how the public site accumulated duplicate hubs and nine index-* articles.

Identity is now the path:<rel> marker written into keywords, which survives the rewrite:

  • The scan indexes by path; the cache carries by_slug, by_path, and duplicates.
  • A DUPLICATES line and SUMMARY.duplicates report a page with more than one article.
  • FERNDESK_RETIRE=1 unpublishes duplicates and articles whose page no longer exists — keeping the canonical article, and never touching a hand-written FernDesk article (no source:mintlify marker).

Docs

  • AGENTS.md rewritten as the source of truth for this tree: IA contract, the allowed public products, writing rules, visual rules, what must never be published, the FernDesk sync rules including path identity, and the check commands.
  • README.md and scripts/FERNDESK.md updated for FernDesk (not Mintlify-only), the production-only rule, and the retire path.
  • Retired fake-UI SVG plates and scripts/generate-docs-frames.py deleted.

Test plan

node scripts/check-docs-site.mjs                                  # ok (24 problem pages)
bash scripts/tests/check-docs-site.test.sh                        # ok, incl. 3 new staging cases
python3 scripts/tests/ferndesk-sync-retry.test.py                 # ok, incl. identity + retire
node scripts/tests/docs-ui.test.mjs                               # ok
npm exec --yes --package=mint@4.2.876 -- mint validate            # passed
  • Internal-link audit: 0 broken links, 87 pages / 87 nav entries.
  • Retire logic verified against a simulation of the live Production section (hashed hub slugs, nine index-* copies, a stale staging/index): keeps one canonical per path, retires the rest, skips the hand-written article.

Not in this PR

  • No merge. This stays a draft for Comp review.
  • No DNS or Cloudflare changes.
  • No backend PR; error-code contract checks still pass site-only. Run node scripts/check-docs-site.mjs ../backend if you want the router check too.

Follow-up after merge

Deleting and renaming pages does not remove their FernDesk articles — the sync upserts and never deletes. Once this lands on main, run the sync with retire enabled to unpublish the staging mirror, the duplicate hubs, and the removed pages:

FERNDESK_RETIRE=1 python3 scripts/ferndesk_sync.py

or dispatch the workflow with retire checked. It unpublishes; it never deletes.

@mintlify

mintlify Bot commented Sep 15, 2026

Copy link
Copy Markdown

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated
cortex-foundation-add13747 🟢 Ready View Preview Sep 16, 2026, 1:56 PM

💡 Tip: Enable Automations to automatically generate PRs for you.

@echobt

echobt commented Sep 15, 2026

Copy link
Copy Markdown
Contributor Author

@greptileai

@echobt

echobt commented Sep 15, 2026

Copy link
Copy Markdown
Contributor Author

@greptileai

@echobt

echobt commented Sep 15, 2026

Copy link
Copy Markdown
Contributor Author

@greptileai

@echobt

echobt commented Sep 15, 2026

Copy link
Copy Markdown
Contributor Author

@greptileai

1 similar comment
@echobt

echobt commented Sep 15, 2026

Copy link
Copy Markdown
Contributor Author

@greptileai

echobt and others added 4 commits September 16, 2026 13:52
Restructure the public site around the products that actually exist, remove
every staging entry point, and make FernDesk sync production-only.

Public IA
- docs.json: Get started | Chat | Code | Bot | CLI | API | Changelog, with
  Get started -> Build by product -> API reference -> Operate mirroring a
  platform docs site. Home rewritten in that order, replacing the help-center
  "How can we help" landing.
- Design is gone as a product vertical: pages, tab, footer entry, home card,
  banner, and the five links pointing at it. Its one durable idea — a document
  panel beside a conversation — is Chat's canvas and stays documented there.
- Folded duplicate hubs into their product pages (chat/code/bot/design
  overview -> index, chat/streaming -> chat/how-it-works, code/cli -> CLI,
  platform -> api/overview, getting-started/desktop -> downloads). 87 pages,
  87 nav entries, no orphans, with redirects for every removed path.

Staging
- Removed the staging mirror: no staging pages, nav, redirects, or copy. The
  sync refuses any FERNDESK_TARGET but production, the workflow no longer
  offers a staging choice, and check-docs-site now fails on staging in
  navigation, redirects, or page copy.

FernDesk sync correctness
- Article identity is now the Mintlify `path:<rel>` marker, not the slug.
  FernDesk rewrites a taken slug (`chat` -> `chat-8hul5`), so resolving by slug
  made a cache-losing run miss its article and create another copy — the cause
  of the live site's nine `index-*` articles and duplicate hubs. The scan
  indexes by path, reports duplicates, and the cache carries the path index.
- FERNDESK_RETIRE=1 unpublishes duplicates and articles whose page is gone,
  keeping the canonical article and never touching a hand-written one.

Also: AGENTS.md rewritten as the source of truth for this tree, README and
scripts/FERNDESK.md updated for FernDesk, and the retired fake-UI SVG plates
plus their generator deleted.

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
"Designer" was the upstream renderer's name for the pack, but it reads as the
retired Design product on a site where Design is not a vertical. Name the pack
for what it is.

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
Two drift classes this refactor fixed by hand are now checked, so the next
change cannot quietly reintroduce them.

- **Orphaned pages.** An MDX page no navigation entry reaches still syncs to
  FernDesk and still gets indexed, but no reader can navigate to it. That is
  how the tree grew a second hub for every product (`chat/overview` beside
  `chat/index`). CI now fails on any page the sidebar cannot reach.
- **Catalog drift.** `problems/index.mdx` is hand-maintained while the pages
  beside it are generated in lockstep with the backend. CI now checks both
  directions: every problem page is linked from the index, and every link has
  a page.

Both are covered by new cases in check-docs-site.test.sh (orphan, catalog
missing a page, catalog linking a ghost code).

Content pass alongside it:

- The CLI hub's card grid duplicated the sidebar entry for entry. It now keeps
  a curated set of six cards and lists the rest in a table, so the page adds
  orientation instead of repeating navigation.
- `getting-started/settings` and `security/overview` carried near-identical
  Data & privacy tables. Settings now says where each control lives; Security
  stays the canonical account of what each one stores and means.

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
- The quickstart listed the four surfaces twice: once as a step, then again as
  a card grid. The card grid stays, with its descriptions.
- System status said "check status.cortex.foundation" three times and closed on
  a note about brand colours and domain hosting, which is internal reasoning
  rather than something a reader needs. The page now states what the status
  site covers and when to use it, once.

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant