Skip to main content

gcp-ace docs conventions

Page skeleton: scope follows heading level

The teaching body of a leaf page is fluid - prose, diagrams, and inline :::gotcha warnings next to the topic they warn about. Reference blocks (:::numbers, :::facts, :::steps, :::practice, :::compare, :::recall, :::troubleshoot, :::cmd, :::decision) are placed by scope:

  • Section-scoped block → stays under the ## heading it belongs to. Example: :::facts[Custom role facts] lives under ## Custom roles because it is only about custom roles.
  • Page-wide block → moves to a trailing ## Recap heading, so it is not visually trapped under (and mistaken for) the last content section. Example: :::cmd[Working with roles] and :::decision[Which role kind?] compare/apply to all role kinds, so they live under ## Recap.

Rules:

  • Gotchas never move to Recap - they are contextual, always inline.
  • ## Recap is a plain Markdown H2, not a component. It auto-appears in the right-rail table of contents. Blocks inside keep their own card styling.
  • Only add Recap when a page actually has page-wide blocks. Short pages whose blocks already sit at page level (no content ## heading above them) need no Recap.
  • Recap holds the page-wide blocks in their existing relative order; never edit the text inside a block, only relocate the whole block.

Directive vocabulary - pick by what the content IS, not by habit

:::numbers renders as "Numbers to memorize" - use it only when the body contains a real digit (a limit, a quota, a percentage). A block with no digit in it is not a numbers block, no matter how bulleted it looks. npm run validate:gcp-directives fails a :::numbers block with no digit in its body - this is the exact bug this whole vocabulary exists to prevent (a security warning was once filed under "Numbers to memorize").

  • :::facts - N named terms/items, each with a short description. No digits, no order, no warning, no comparison. The default choice for a definitional bullet list.
  • :::steps - a sequence where the ORDER is the content (build order, request path, evaluation order). Auto-numbered even if authored as bullets.
  • :::practice - one imperative recommendation + its rationale. Not a trap (:::gotcha), not a choice between named options (:::decision/:::compare).
  • :::compare - two or three named things contrasted, with no rule for which to pick. If there IS a pick rule, it's :::decision with a pick-when instead.
  • :::recall - one-directional exam pattern-match: "if the question says X, the answer is Y." No second option, no table - that's what makes it not a :::decision.
  • :::troubleshoot - symptom → cause → fix. Diagnostic, not a choice. Author as a plain bulleted list, one bullet per issue, each bullet a full {symptom, explanation} unit in prose with a bolded lead phrase - the same list rendering as :::facts/:::numbers. Do not try to force separate symptom/cause/fix fields per item: a <Branches>-style symptom → fix reduction was designed and rejected, because real troubleshooting content doesn't compress to a short "fix" chip without losing the "why".
  • :::gotcha - a genuine trap: a wrong assumption that will cause a real failure. Not every piece of advice is a gotcha.
  • :::decision - a question-shaped title + pick-when="..." + 2+ named alternatives with contrasting properties, usually a <Branches>/<Table>.

Canonical example: 20. iam-and-access/10. roles.md.