packages/docs/AGENTS.md
Public documentation, Mintlify. Everything here is merchant- and developer-facing — write for a person reading it, never for a model consuming it. Read the rootAGENTS.md first for cross-cutting rules.
mint dev previews locally; docs.json owns navigation and redirects.
One page, one job
Every page serves exactly one reader need. Mixing two on a page is the failure mode that makes docs feel cluttered even when each paragraph is good.
A reference page that explains is a reference page nobody can scan. Split instead.
Writing
- Second person, active voice. “You can configure”, not “Users can configure”.
- One idea per sentence, under 25 words. Two to four sentences per paragraph.
- Lead with the answer. Context comes after it, not before.
- Sentence case headings, shaped by reader intent: “Branch on a condition”, not “Choice step”. Never skip a heading level.
- One term per concept, everywhere. Merchant-facing terms are fixed by
backend/app/chat/prompts/vocabulary.md— read it before naming a primitive. - Define an unfamiliar term where it appears rather than linking away.
- Cut filler: “in order to”, “simply”, “it’s worth noting”, “please note”.
- Cut opinions dressed as facts: “powerful”, “seamless”, “robust”, “just”.
- Every code block gets a language tag. Every image gets alt text — a reader using a screen reader and a model reading the page both depend on it.
- Internal links are relative paths (
/automations/step-types), never absolute URLs. - Test code examples before publishing. An example that does not run is worse than none.
Navigation
- Five to seven items per group. Depth beats breadth.
- Nothing important more than two clicks from the top.
- Name groups for what the reader is doing: verbs for tasks (“Deploy”), nouns for lookup areas (“API reference”). Four words or fewer.
- A page that is two paragraphs is a section of another page, not a nav slot.
Nothing internal ships here
This site is public. A reader outside the company reads every page, so it describes the product’s behaviour and never the platform behind it: no service, table, queue or module names, no file paths from this repo, no ticket ids, no unreleased work, and nothing about who runs what where. Vendors and infrastructure stay unnamed unless a merchant chooses them - a connection they connect to is theirs to know about; the platform’s own hosting, model provider or datastore is not. Reality is documented, not confessed. Where behaviour is untidy - a status whose casing varies, a field kept for compatibility - write the rule a reader should follow (“match a status case-insensitively”) rather than the history that produced it. Anything a reader cannot act on is either internal or noise, and both belong in the vault instead. Screenshots, logs and error text carry internals as readily as prose does. Read what is inside one before pasting it.Things specific to this repo
- Step-type field tables are generated. Everything between
{/* fields:<type> start */}and{/* fields:<type> end */}inautomations/step-types.mdxcomes from the engine viabackend/scripts/build_step_type_docs.py. Never hand-edit inside the markers; change the source and regenerate.--checkfails CI when they drift. - Renaming a heading moves its anchor. Mintlify derives anchors from heading text
and supports no override, so a rename silently breaks every
#anchorlink and the redirects indocs.json. Before renaming, grep the repo for the old anchor —automations/step-typesanchors are linked from the backend prompts too, not only from docs. - A step type gets an anchor; an agent gets a page.
insightsandstorefront-builderhave their own pages because they are named products with their own surface in the app. The other step types are anchors on one reference page, with redirects preserving the old per-step URLs. Do not add a page per step type. - Prefer editing an existing page over adding one. Search before you write.