跳到內容

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.

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.

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).