Decision log
本頁內容尚未翻譯。
Status
Stable· Last verified 2026-07-12
Lightweight architecture decision records (ADRs). Append new ones; don’t rewrite history — supersede instead.
D-001 — Keep the name discord-platform-atlas
Section titled “D-001 — Keep the name discord-platform-atlas”Context. The name was a hypothesis to challenge.
Decision. Keep it. “Atlas” captures the core promise — a navigable map of a
sprawling platform — better than alternatives (discord-dev-handbook,
discord-compendium, discord-codex). It reads well as a site title and a repo.
Alternatives. discord-dev-atlas (redundant “dev”), discord-platform-guide
(narrower than a reference+research base).
Consequences. Framing is “map + reference + lab,” which shapes the IA below.
D-002 — One content source, rendered two ways
Section titled “D-002 — One content source, rendered two ways”Context. Vision wants both a GitHub-browsable repo and a documentation website.
Maintaining parallel copies rots.
Decision. Author all prose once in site/src/content/docs/ as plain
Markdown with a small top-of-page metadata banner. Starlight renders the website;
GitHub renders the same Markdown acceptably. The root README is the GitHub entry
point and links into these files.
Alternatives. (a) Separate docs/ + a sync script (drift risk). (b) MDX
everywhere (poor raw-GitHub rendering). (c) Docusaurus/VitePress (fine, but
Starlight’s i18n is the cleanest fit — D-004).
Consequences. We avoid MDX except for the landing page; metadata is duplicated
minimally (frontmatter + one banner line) by design, for dual rendering.
D-003 — Verifiability is a first-class feature
Section titled “D-003 — Verifiability is a first-class feature”Context. Discord changes fast; confident-but-wrong docs are worse than honest
gaps.
Decision. Every page carries status, lastVerified, apiVersion, and
sources; inside pages we separate Verified / Observation / Hypothesis.
Alternatives. Undated prose (the usual blog failure mode).
Consequences. Slightly heavier authoring; much higher trust and a clear
re-verification workflow. Enforced via the frontmatter contract.
D-004 — Astro + Starlight for the site
Section titled “D-004 — Astro + Starlight for the site”Context. Need i18n (en/ja/zh-tw), Markdown-first authoring, fast static output,
built-in search, easy hosting.
Decision. Astro + Starlight. First-class i18n with per-locale directories and
automatic English fallback; Pagefind search; trivial deploy to Pages/Netlify/etc.
Alternatives. Docusaurus (React-heavy, heavier i18n), VitePress (lighter i18n),
MkDocs Material (Python; i18n via plugins).
Consequences. Content lives in a Starlight collection; the extended frontmatter
schema is defined in site/src/content.config.ts.
D-005 — Trilingual with honest fallback
Section titled “D-005 — Trilingual with honest fallback”Context. Full translation of a large, fast-moving corpus is unsustainable at v0.1. Decision. English is the source of truth; translate the highest-value pages first (landing, getting-started, the webhook headline). Untranslated pages fall back to English rather than shipping machine translations. Coverage is tracked in translation-status. Alternatives. Machine-translate everything (low trust), or English-only (fails the multilingual requirement). Consequences. The i18n system is real and demonstrated; coverage grows over time without blocking releases.
D-006 — Examples are minimal, runnable, and least-privilege
Section titled “D-006 — Examples are minimal, runnable, and least-privilege”Context. “Prefer concrete demonstrations.”
Decision. Each example is the smallest thing that teaches one capability,
ships its own README + .env.example, requests the fewest scopes/intents, and
documents cleanup/revocation. webhook-minimal uses zero dependencies
(Node global fetch).
Alternatives. One large kitchen-sink bot (hard to learn from, over-permissioned).
Consequences. More folders, each independently understandable and safe to run.
D-007 — Secrets can’t be committed by construction
Section titled “D-007 — Secrets can’t be committed by construction”Context. The corpus is full of tokens/URLs; accidental commits are the top risk.
Decision. .gitignore blocks .env* (except examples), keys, and common leak
filenames; only *.example templates are tracked; a check:secrets scanner flags
token/webhook shapes and DISCORD_* secret assignments. Guidance says rotate
first on leak. The *secret* ignore pattern must un-ignore
scripts/check-secrets.mjs so the scanner itself stays tracked.
Alternatives. Rely on contributor discipline (insufficient).
Consequences. Safe-by-default repo; pnpm check:secrets, optional
pnpm hooks:install pre-commit, and CI all run the scanner.
D-008 — Document ToS boundaries, never implement them
Section titled “D-008 — Document ToS boundaries, never implement them”Context. Self-bots/token-abuse are real platform boundaries readers ask about. Decision. Describe them as platform boundaries / risks for defensive understanding, clearly labeled, with no working implementation. Alternatives. Ignore them (leaves readers to unsafe third-party guides) or implement them (violates ToS and this project’s principles). Consequences. Honest coverage of limits without becoming an abuse how-to.
D-009 — One command for the quality bar (pnpm check)
Section titled “D-009 — One command for the quality bar (pnpm check)”Context. Docs, examples, and scanners can drift independently; contributors
need a single local gate that matches CI.
Decision. Root scripts: pnpm test (all offline example tests),
pnpm check:secrets, pnpm site:build, pnpm check:links, and a composite
pnpm check. GitHub Actions runs the same sequence on push/PR to main.
Alternatives. Per-package scripts only (easy to forget a gate).
Consequences. Review/polish work has a reproducible bar; link and secret
regressions fail before merge.
D-010 — Interaction endpoints: baseline + atlas hardening
Section titled “D-010 — Interaction endpoints: baseline + atlas hardening”Context. Official docs require Ed25519 over timestamp + rawBody and 401 on
failure. Production endpoints still face replays and oversized bodies.
Decision. The interaction-endpoint example implements the official baseline
plus a 5-minute timestamp skew window, strict hex parsing, a 256 KiB body
cap, and async handler try/catch so Discord always gets a response.
Alternatives. Minimal verify-only sample (teaches less); full framework
middleware (hides the raw-body lesson).
Consequences. Docs and tests teach both the non-negotiable check and the
high-confidence hardening steps.
D-011 — Host docs on Cloudflare Pages; keep source on (private) GitHub
Section titled “D-011 — Host docs on Cloudflare Pages; keep source on (private) GitHub”Context. The atlas needs a public, fast static site and may keep the monorepo
private. GitHub Pages is less ideal for private-source + public-site and is not
the primary CDN we want.
Decision. Cloudflare Pages hosts the static Astro build (site/dist).
GitHub (private OK) is the source of truth. Cloudflare Connect to Git auto-
deploys on push to main. GitHub Actions only runs quality checks (pnpm check),
never publishes. Manual fallback: pnpm site:deploy (Wrangler). Config and
operator runbook live in DEPLOY.md, wrangler.jsonc, and site/public/_headers.
Alternatives. GitHub Pages (private-repo limits / weaker edge story); Netlify
(fine, but we already target *.pages.dev and CF tooling).
Consequences. One push updates both CI status and the public site; secrets
stay out of Pages env (static docs only).