Skip to main content

Freshdesk PR Review Guidelines

Scope

This guideline applies specifically to PRs where mintlify[bot] turns facts mined from resolved Freshdesk support tickets into new MDX content — typically FAQ entries or short notes added to existing pages. It does not restate general MSTP or quality rules. For those, see Cashfree Documentation Content Guidelines and .github/AI_AGENT_QUALITY_QUICK_REFERENCE.md. Use this file alongside those, not instead of them.
A condensed, shareable version of the review-process rules in this file (sections below on the two-layer model, hallucination checks, and the standing checklist) is also published as an Artifact: Doc PR Review Protocol. This file is the fuller, maintained reference — update this one first if the two ever diverge.

The two-layer review model

Each PR of this type typically passes through two different reviewers, checking two different things:
  • Factual reviewer — usually someone close to the support side (the engineer who resolved the ticket, or a colleague of theirs). Confirms the fact itself is true. Don’t relitigate a fact this reviewer already confirmed unless it looks internally inconsistent with something else in the docs (see Duplication, contradiction, and propagation, below).
  • Required approver — the person named in .github/workflows/require-approval.yml. Owns MSTP/CLAUDE.md compliance and cross-document consistency. A factual approval from someone else does not satisfy this gate, even if the PR shows as “approved” by another reviewer — check who actually approved, not just whether an approval exists.

Hallucination-prone spots

Check these first, before a close read of the rest of the diff:
  • Any newly introduced URL or domain. Confirm it resolves, and that it matches what similar existing docs already use for the same destination. A domain that appears nowhere else in the repo is a signal, not proof — but check it before shipping it.
  • Any claim that a prebuilt automation or integration already exists (“there’s a flow for that,” “you can use…”). Verify this against the literal wording of the source ticket, or ask — don’t accept it because it reads plausibly.
  • The bot’s own fix-up commits, if present. When review comments already produced a follow-up commit, diff it against the original before reading the PR as a whole — it’s a short, dense list of exactly what a domain expert already caught, and it calibrates what to look for on the next PR in the series.

Mechanical terminology fixes

These recur often enough across Freshdesk-sourced PRs to check with a grep before any close reading, rather than relying on catching them by eye:

Redirect-path hygiene

docs.json has a redirects array mapping old source paths to current destination paths. Older content in the repo sometimes still links the stale source path directly (it still works, because of the redirect, so it’s easy to miss). Before reusing a path found in existing content as a citation for new content, check whether it appears as a source in that array — if it does, link the destination instead. Two confirmed live examples: .../subscription/mandate/fetch.../subscription/fetch-subscription, and .../subscription/mandate/create.../subscription/create-subscription.

Duplication, contradiction, and propagation check

Before accepting where the bot placed a new fact, grep the repo for the concept it describes (a feature name, a dashboard field, a setting). Three distinct questions, not one:
  • Duplication — does the same concept already exist elsewhere in different words? If so, don’t leave two disconnected prose descriptions to drift apart over time. Prefer linking both to the authoritative source instead — for example, rather than cross-referencing two FAQ entries to each other, link both to the actual API parameter they describe (plan_max_amount, plan_max_cycles) so there’s one source of truth, not two paraphrases of it.
  • Contradiction — does the new fact conflict with something already documented elsewhere, rather than just restating it? This is a stop-and-ask, not a silent overwrite of either version — CLAUDE.md’s own “When to Escalate to a Human” section already covers this case (“Information doesn’t match between the OpenAPI spec and existing docs — which is correct?”). Don’t guess which one is right.
  • Propagation — when a fix corrects something in the PR itself (a stale redirect path, a broken or near-empty domain, an outdated dashboard URL), grep for the same pattern elsewhere in the repo. Don’t assume the PR’s own diff is the only place that needs it. Document what else you find and ask whether it’s worth a follow-up — don’t silently expand the PR’s scope to fix it inline. Confirmed examples from this repo: payments/manage/monitor.mdx still links the near-empty status.cashfree.com stub instead of the verified-live statuspage.cashfree.com; several files still cite “Create Subscription API” via the stale .../mandate/create redirect instead of the canonical path.

When something can’t be verified from the docs alone, write the actual question

A vague flag (“this might be wrong,” “not sure about this”) doesn’t get answered by anyone. A specific, answerable question does. When a fact depends on internal system behavior the docs repo alone can’t confirm — usually because the accurate wording requires naming an actor (who does this: Cashfree’s checkout, or the third-party platform?) — write out:
  1. The exact sentence in question.
  2. The exact ambiguity (usually: which of two or three plausible actors performs the action).
  3. The candidate answers, so the person answering can reply in one line rather than having to reconstruct the question themselves.
For example, rather than flagging “GSTIN information is passed in the Additional Information section of the Shopify order” as vaguely passive, the actionable version is: “which side actually populates that field — Cashfree’s checkout, or Shopify itself?” The same shape applies to unverifiable dashboard deep links (name the two candidate paths, ask which is current) or any other claim that depends on live system or dashboard behavior.

FAQ architecture decision

When a Freshdesk-sourced PR adds FAQ content, decide deliberately whether it belongs inline on the page it landed on, or deserves its own reusable snippet — don’t let wherever the bot happened to place it become the default. Signal it should become a shared snippet: the same FAQ content is genuinely useful from more than one entry point — typically both a product-doc page and the corresponding /help section page (mirroring how a merchant might look for it either while reading integration docs, or while searching Help directly). The pattern, once that’s the call (worked example: One Click Checkout, added in this repo):
  1. Create the snippet at snippets/faqs/payments/<topic>.mdx. Every existing file in that folder, without exception, wraps its entries in <AccordionGroup>, and each <Accordion> includes an onClick={() => posthog.capture('Accordion Clicked', { title: "..." })} handler and a faqFeedback iframe widget (https://www.cashfree.com/devstudio/preview/pg/embed/faqFeedback?section=<topic>%2Ffaqs%23<slugified-title>). Match this exactly — it’s a 100%-consistent convention across the folder, not an optional flourish.
  2. Create a product-doc FAQ page (pattern: payments/<product>/faq.mdx, or a hyphenated sibling name like payments/checkout/one-click-checkout-faq.mdx when the product doesn’t have its own dedicated folder) containing only:
  3. Create the matching help-section page at help/<topic>/faqs/faqs.mdx, importing the same snippet the same way.
  4. Wire both new pages into docs.json: the product-doc page into its product’s nav group (Payments tab), the help page into the “Payment Gateway” group (Help tab) alongside the other help/*/faqs/faqs entries.
  5. If FAQ content already lived inline somewhere (e.g. in a snippets/pg/* installation guide), remove it from there and replace it with a short pointer link to the new FAQ page — don’t leave the same content in two places.
If the FAQ content is genuinely page-specific (a first-ever FAQ section on a page that has no natural second entry point), CLAUDE.md’s own Interactive Components example still models FAQs as <Accordion> — use that, without the snippet/help-page machinery, rather than inventing a bold-question/plain-paragraph format.

Standing checklist and a tooling note

Freshdesk-sourced content is prose added to existing pages, so the frontmatter and code sections of CLAUDE.md’s Pre-Publication Checklist are usually no-ops — confirm that rather than skip it, and always check whether docs.json silently needed a new nav entry. node util/checkDocs.mjs has no timeout on its external-link check, so one slow or unresponsive URL can stall the whole scan indefinitely — if it hangs past the initial file scan, kill it and fall back to a targeted grep against the checklist for just the changed files.