Documentation
This guide owns docs placement, the doc rules, i18n, docs sync, the coverage lifecycle and the link strategy.Placement and rules
- English source lives in
docs/.docs/zh-CN/**anddocs/ja-JP/**are generated; do not edit them directly. - i18n pipeline: update the English page, adjust
docs/.i18n/glossary.zh-CN.json, then runscripts/docs-i18n. - Internal doc links are root-relative with no
.mdor.mdxextension, for example[Config](/admin/gateway/configuration). When a page is mapped to a different site route, use its absolutehttps://docs.wednesdayai.dev/...URL so unchanged sync output targets the published page. - Headings avoid em dashes and apostrophes, because they break anchor generation.
- Content must be generic: no personal device names, hostnames, or paths. Use placeholders such as
user@gateway-host. - Store screenshots under
docs/.screenshots/(gitignored). Never commit screenshots or leave them at the repo root. - Frontmatter uses
title,summaryandread_when. Developer pages addaudience: developer. - After editing docs, run
pnpm check:docs(format, docs lint and the link audit).pnpm docs:listlists docs for a quick sanity check.
Docs sync
scripts/docs-sync.sh copies English core docs to the docs site repository, and scripts/docs-drift.mjs reports which site pages are likely stale. Both map a core path to a site path, and the two maps must stay identical:
docs/contributing/*maps todevelopers/contributing/*.CONTRIBUTING.mdmaps to the single pagedevelopers/contributing, with site frontmatter prepended.- Other prefixes follow the persona rules in the scripts (
gateway/toadmin/gateway/, and so on).
scripts/docs-sync.sh --dry-run to see the mapping before a real sync.
Docs coverage lifecycle
- Source of truth:
docs-surface.yamlat the repo root maps every documentable surface (hook, SDK export, config key, channel, provider, CLI command, concept) to its expected docs page. It is the single mapping; the docs repository never holds a second copy. - Two tiers:
- A cheap deterministic gate runs on every PR through
scripts/docs-surface-check.mjs.--mode=source(core CI) checks that eachsourcepath still exists.--mode=pages --docs-root=<docs checkout>(docs CI) checks that eachdocs_page, plus optional#anchor, resolves. - A periodic deep audit (
/wai:surface-audit, plugin-owned) enumerates real surfaces and finds new undocumented ones the cheap gate cannot see.
- A cheap deterministic gate runs on every PR through
- Advisory only: branch protection is unavailable on the free-plan private repo, so the check never hard-fails a merge. It exits
0and emits GitHub::warning::annotations.--strictgives a non-zero exit for local use. - Cadence: the cheap gate runs per PR. Run the deep audit each release cycle and after large surface changes.
- Follow-ups: a detected gap becomes a tracked follow-up, keyed by the surface
idso it is idempotent: a GitHub issue (labeldocs-coverage) and/or a/wailedger item. Entries withcoverage: gaporwrongcarry the known-bad baseline until a docs PR flips them todocumented.
Link strategy
The core repository is private. A link resolves only if the reader can reach its target.SUPPORT.md and the CONTRIBUTING.md rendering state the security contact (security@expansionx.com.au) inline, so the public path never depends on reading SECURITY.md.