diff --git a/.claude/CLAUDE.md b/.claude/CLAUDE.md index afb6d1ace..c48d71a32 100644 --- a/.claude/CLAUDE.md +++ b/.claude/CLAUDE.md @@ -108,7 +108,9 @@ for full ownership details. ### Architecture documentation - ADRs go in `docs/architecture/adr/` with format `####-title.md` -- Follow existing ADR structure (Status, Context, Decision, Consequences) +- Follow the MADR structure from the template on the ADR index (`docs/architecture/adr/index.mdx`): + frontmatter (`adr`, `status`, `date`, `tags`), Context and problem statement, Considered options, + Decision outcome ## Testing before committing diff --git a/custom-words.txt b/custom-words.txt index b0efcb94b..537626715 100644 --- a/custom-words.txt +++ b/custom-words.txt @@ -52,6 +52,7 @@ LLDB Lucidchart Mailcatcher minio +mortems MVVM NGRX Napi @@ -107,6 +108,7 @@ typecheck typechecks typesafe udeps +ungated unsynchronized WCAG weweave diff --git a/docs/architecture/adr/0033-adopt-mermaid-diagram-standard.md b/docs/architecture/adr/0033-adopt-mermaid-diagram-standard.md index 57be3db80..5749003a2 100644 --- a/docs/architecture/adr/0033-adopt-mermaid-diagram-standard.md +++ b/docs/architecture/adr/0033-adopt-mermaid-diagram-standard.md @@ -37,9 +37,9 @@ audience-specific views -- requires substantial rework per audience in practice. ## Decision outcome Chosen option: **Mermaid with defined conventions**, published as the -[diagram standard](../../contributing/diagrams.md) on the contributing site. The standard is the -living reference and its rules evolve by PR without superseding this decision. This ADR is -superseded only if the chosen option itself changes. A snapshot of the rules at adoption: +[diagram standard](../../contributing/documentation/diagrams.md) on the contributing site. The +standard is the living reference and its rules evolve by PR without superseding this decision. This +ADR is superseded only if the chosen option itself changes. A snapshot of the rules at adoption: 1. Diagrams are Mermaid source text, nothing else: as Mermaid code blocks, or, if in Confluence, via Macro Pack's Mermaid diagram in text-input mode. @@ -80,12 +80,12 @@ superseded only if the chosen option itself changes. A snapshot of the rules at ### Plan -The standard is published at Contributing › Diagrams, and the bulk of the contributing site's -existing diagrams (PlantUML/Kroki sources, static diagram assets, and source-less images) have been -converted to comply, so the site becomes the reference implementation of the standard, with the -exceptions noted below. Elsewhere, legacy diagrams convert when their docs are next touched: images -and non-Mermaid sources in repos become Mermaid code blocks, and Confluence attachments and images -become Macro Pack's Mermaid diagram in text-input mode. +The standard is published at Contributing › Documentation › Diagrams, and the bulk of the +contributing site's existing diagrams (PlantUML/Kroki sources, static diagram assets, and +source-less images) have been converted to comply, so the site becomes the reference implementation +of the standard, with the exceptions noted below. Elsewhere, legacy diagrams convert when their docs +are next touched: images and non-Mermaid sources in repos become Mermaid code blocks, and Confluence +attachments and images become Macro Pack's Mermaid diagram in text-input mode. The remaining adoption work is delegated to its owners: diff --git a/docs/architecture/adr/0034-adopt-engineering-documentation-standard.md b/docs/architecture/adr/0034-adopt-engineering-documentation-standard.md index 3382a22c1..189b17e58 100644 --- a/docs/architecture/adr/0034-adopt-engineering-documentation-standard.md +++ b/docs/architecture/adr/0034-adopt-engineering-documentation-standard.md @@ -1,6 +1,6 @@ --- adr: "0034" -status: Proposed +status: Accepted date: 2026-08-05 tags: [clients, mobile, server, sdk] --- @@ -38,10 +38,10 @@ Confluence against a proposed routing model, confirming these gaps. ## Decision outcome -Chosen option: **one org-wide, docs-as-code documentation standard**, published as the Documentation -section under Contributing on this site. The standard is the living reference. Its rules evolve by -PR without superseding this decision and this ADR is superseded only if the model itself changes. A -snapshot of the rules at adoption: +Chosen option: **one org-wide, docs-as-code documentation standard**, published as the +[Documentation section](../../contributing/documentation/index.md). The standard is the living +reference. Its rules evolve by PR without superseding this decision and this ADR is superseded only +if the model itself changes. A snapshot of the rules at adoption: 1. **Public by default**. Private content is limited to documentation about working at Bitwarden and sensitive information. @@ -54,7 +54,7 @@ snapshot of the rules at adoption: Diagrams follow the separate diagram standard adopted in [ADR-0033](./0033-adopt-mermaid-diagram-standard.md), which keeps its own living reference at -Contributing › Diagrams. +Contributing › Documentation › Diagrams. AI instruction files are explicitly not documentation and are out of the standard's scope. Their guidance lives with the AI tooling. diff --git a/docs/architecture/adr/index.mdx b/docs/architecture/adr/index.mdx index 10f220e9a..d398292ff 100644 --- a/docs/architecture/adr/index.mdx +++ b/docs/architecture/adr/index.mdx @@ -75,6 +75,68 @@ the thinking process and alternatives considered rather than simply stating what if an ADR doesn't cover every edge case or alternative it provides valuable context and can be refined through discussion. +## Format + +ADRs follow the [MADR](https://adr.github.io/madr/) structure: a context and problem statement, the +considered options, and the decision outcome with its consequences. Start from the template below. + +Each ADR is a file named `NNNN-short-title.md` in `docs/architecture/adr/`, numbered with the next +unused number. Refer to an ADR elsewhere by that number as ADR-NNNN, linking the file relatively so +the reference survives a move of this section. + +
+ADR template + +Delete the guidance comments before opening the pull request. + +```text +--- +adr: "NNNN" +status: Proposed +date: YYYY-MM-DD +tags: [clients, mobile, server, sdk] +--- + +# NNNN - Short imperative title + + + +{/* Optional "## Notation" section here if the ADR relies on notation (RFC 2119 + keywords, symbols). Delete when unused. */} + +## Context and problem statement + +{/* 2–4 paragraphs. What situation forces a decision? What breaks or + stays painful if we decide nothing? Link code, issues, and prior ADRs. */} + +## Considered options + +- **Option A:** one-line description. +- **Option B:** one-line description. + +{/* Optional per-option subsections with pros/cons when the tradeoffs + need more than a line. Include "do nothing" when it is a real option. */} + +## Decision outcome + +Chosen option: **Option A**, because {decisive reason}. + +### Positive consequences + +- ... + +### Negative consequences + +- ... + +### Plan + +{/* How the decision takes effect: the follow-up work, migrations, and owners. + Delete when the ADR needs no follow-up. */} +``` + +
+ ## Status definition ADRs progress through different statuses throughout their lifecycle. Understanding these statuses diff --git a/docs/contributing/documentation/component-documentation.md b/docs/contributing/documentation/component-documentation.md new file mode 100644 index 000000000..af85177d1 --- /dev/null +++ b/docs/contributing/documentation/component-documentation.md @@ -0,0 +1,62 @@ +--- +sidebar_position: 1 +--- + +# Component documentation + +**Audience:** Bitwarden engineers and AI agents writing or consuming in-repo documentation. + +Notation follows the [documentation standard's Notation](./index.md#notation). These requirements +hold for every repo for as long as it lives, enforced by review and the doc-parity plugin. New +repositories satisfy them at initialization by starting from +[bitwarden/template](https://github.com/bitwarden/template). Existing repos converge per +[Changes to this standard](./index.md#changes-to-this-standard). Additional local guidance MAY be +layered on top, as each situation dictates. + +Any component that other engineers or agents consume (that is, it exposes a public interface) MUST +have an **entry point for its scope's documentation**, at every scope from a single component to the +repo root. The entry point lives where the component's ecosystem surfaces documentation: + +- At **component scope**, the entry point is the `README.md`, which registries render for packaged + components (a crate, an npm package, a NuGet project). Rust crates keep the README and the rustdoc + landing page one artifact with `#![doc = include_str!("../README.md")]`. +- **Below component scope**, the entry point is the language's module-level documentation where it + exists (`//!` in Rust), since a README there duplicates what the toolchain already owns and no + tooling surfaces it. It SHOULD be lint-enforced where the language supports it (Rust's + `missing_docs`). +- At **container and system scopes** (a container grouping several components, the repo root), the + entry point is a `README.md`, since no language ecosystem claims them. + +Whatever its carrier, the entry point MUST contain: + +1. **Purpose:** what problem this component solves, in 1–3 sentences. +2. **Key concepts:** the domain model or invariants a consumer must know (e.g., `libs/state`'s + data-loss warning on key renames; `bitwarden-crypto`'s `derive_`/`make_` naming rules). +3. **Usage:** the primary entry points, with a short code sample where the API is not self-evident. +4. **Gotchas / constraints:** the things that bite people (e.g., `libs/auth`'s "do not add new code + here" notice). This section MUST exist when such constraints do and MUST NOT exist when they do + not. + +Documentation grows outward from the entry point of the +[lowest common ancestor](./index.md#where-documentation-lives-rules-1-2) of the code it describes. A +guide spanning several components therefore belongs to their parent scope: + +1. Everything starts at the scope's entry point. +2. A single topic that deserves its own document becomes a named `.md` next to the code it + describes, linked from the entry point (`apps/browser/src/autofill/lifecycle.design.md` is the + exemplar). +3. When the scope's documentation outgrows this, it splits into a `docs/` folder (exactly that name, + lowercase) at the scope root. `docs/` exists only beside the entry point it extends: at the repo + root (`clients/docs/cipher-types.md` is the exemplar) or a component with its own entry point + (`util/Seeder/Seeds/docs/`), never an arbitrary subdirectory. + +Scopes layer and multiple perspectives exist. A parent scope's documentation MAY describe the same +code at a higher altitude, sanding off detail the deeper docs own and linking down to them, and the +same subject MAY be documented separately per audience. Both are approved. Duplication is two +artifacts sharing one perspective. + +Below component scope, reference documentation is code: doc comments on public symbols, reviewed and +merged with functionality, lint-enforced where the platform supports it. Doc comments MUST follow +the language's documentation norms for structure and detail. Where not enforced by the type system, +doc comments MUST say what a caller needs (behavior, invariants, error cases). Repos with doc CI +SHOULD fail the build on broken docs (the `sdk-internal` `cargo doc -D warnings` pattern). diff --git a/docs/contributing/diagrams.md b/docs/contributing/documentation/diagrams.md similarity index 96% rename from docs/contributing/diagrams.md rename to docs/contributing/documentation/diagrams.md index 84618fe1b..5dd640bc5 100644 --- a/docs/contributing/diagrams.md +++ b/docs/contributing/documentation/diagrams.md @@ -1,5 +1,5 @@ --- -sidebar_position: 2 +sidebar_position: 5 --- # Diagram standard @@ -103,14 +103,14 @@ vocabulary. The example above is at context level. C4 is adopted as a **mental model only**. We are explicitly **NOT** adopting any C4 tooling/DSL. -## Ownership and currency (rules 7 and 8) +## Ownership and updates (rules 7 and 8) -- The owner is CODEOWNERS for in-repo docs and the page's owning team on Confluence. +- The owner is `CODEOWNERS` for in-repo docs and the page's owning team on Confluence. - Updates land in the same PR or page edit as the change the diagram depicts. A diagram known to be wrong is deleted or updated rather than left to mislead. - Every repo's root `CLAUDE.md` MUST carry the base documentation obligations, which cover diagrams: when you change code that a diagram describes, update the diagram in the same change. The - doc-currency plugin in [bitwarden/ai-plugins](https://github.com/bitwarden/ai-plugins) distributes + doc-parity plugin in [bitwarden/ai-plugins](https://github.com/bitwarden/ai-plugins) distributes the obligation and enforces it across every documented scope above a change. The plugin's own documentation owns the mechanism. - Agent-authored diagrams follow the same rules. Generated diagrams MUST carry a perspective caption diff --git a/docs/contributing/documentation/index.md b/docs/contributing/documentation/index.md new file mode 100644 index 000000000..762451237 --- /dev/null +++ b/docs/contributing/documentation/index.md @@ -0,0 +1,278 @@ +--- +sidebar_position: 2 +sidebar_label: Documentation +--- + +# Documentation standard + +**Audience:** Bitwarden engineers who write and maintain technical documentation, and AI agents that +read documentation to work in our codebases. External contributors are a secondary audience. + +## Notation + +The keywords MUST, MUST NOT, SHOULD, SHOULD NOT, and MAY are to be interpreted as described in +[RFC 2119](https://www.rfc-editor.org/rfc/rfc2119). + +`repo` is short for repository, referring to a git repository. + +`doc` or `docs` is short for documentation. + +`PR` is short for pull request. + +`RCA` is short for root cause analysis, the post-incident review document. + +`CI` is short for continuous integration. + +`system`, `container`, and `component` describe software scope as the +[diagram standard](./diagrams.md) defines them: C4 vocabulary, where a component is a major part +inside one container (a library, a crate, a feature root). + +`›` marks a location in a site or page hierarchy ("contributing.bitwarden.com › Architecture"). + +`→` marks a routing outcome ("cross-repo architecture → contributing.bitwarden.com"). Read as +"then". + +## The standard + +1. **Public by default**. Private content is limited to documentation about working at Bitwarden and + sensitive information. +2. **Located at the lowest common ancestor** of what is described. +3. **Every doc has an audience**. AI agents and humans are both first-class audiences and + maintainers. +4. **Always up to date**. Doc maintenance is a top priority and happens alongside changes to what it + describes. +5. **Discoverable and unified**, enforced by the style guide published here. + +## Where documentation lives (rules 1, 2) + +The **lowest common ancestor** of a doc's subject is the deepest scope that contains everything it +describes: a component for component docs, a repo root for repo-spanning guides, +contributing.bitwarden.com for subjects above any one repo, and a private location when +[rule 1](#private-content) removes the public homes from consideration. Every doc lives there and +nowhere else. Close to code is the common case: in-repo docs ride the same PR and review as the +change and are visible to AI agents working in the tree. + +Within a scope, documentation is one growing artifact: it starts at the scope's entry point, +typically its `README.md`, and splits into a `docs/` folder beside it when it outgrows one file, per +[Component documentation](./component-documentation.md). Wherever this standard says `README.md` or +`docs/`, it means that artifact at either stage. + +AI instruction files (`CLAUDE.md`, rules, skills) are not documentation: they are instructions on +how to behave and how to consume documentation. This standard does not govern them, and content that +belongs in documentation MUST NOT live in an instruction file, since that would give it a second +home. + +One home holds one **perspective**: the audience a doc serves and the question it answers. A +different audience or altitude is a different [perspective](./diagrams.md), not a duplicate. Link +related perspectives to each other, and link instead of copying, since duplicated guidance always +diverges. + +### Decision rule + +Apply in order. First match wins: + +1. Is it [Private content](#private-content)? → a **private location:** + [bitwarden/tech-breakdowns](https://github.com/bitwarden/tech-breakdowns)bitwarden/tech-breakdowns + for tech breakdowns and work specifications, **Confluence** in the owning team's space for + everything else. +2. Does it describe **code in one repo**? → **that repo**, in the owning scope's + [`README.md` or `docs/`](./component-documentation.md). +3. Is it **how to contribute or build**, **architecture spanning repos**, or an **architectural + decision**? → **contributing.bitwarden.com** + ([bitwarden/contributing-docs](https://github.com/bitwarden/contributing-docs)), behind the + `` audience gate when the concern is internal-only. + +:::note + +1. This rule fires first because `` gating is not secrecy: it is convenience and + effective communication. +2. Repo-specific practice guides (testing, troubleshooting, tooling tips coupled to the repo's + scripts or lint config) follow this rule. +3. Environment setup and onboarding follow this rule even when repo-specific. Internal content does + not move to Confluence merely for being internal. It MUST be sensitive or organizational. + +::: + +### Private content + +Exactly two categories of content are private: + +- **Content Bitwarden cannot expose**: sensitive infrastructure, security-operational detail. + Feature and work planning also belong here, since direction is private until work begins. +- **Content about working at Bitwarden** rather than working on its code: people processes, on-call, + incident response, and team/org process. + +Everything else defaults to public. Bitwarden builds in the open and public docs serve external +contributors without special access. The litmus test is + +> Anything about **how to write or build Bitwarden code** goes somewhere public. + +Confluence holds what we cannot expose and the business of working at Bitwarden, not engineering +knowledge. + +### Reverse routing table + +Where each kind of documentation lives, grouped by home. Owners follow the +[ownership rule](#owners). The Format column links the page that owns the type's format, where one +exists. When more than one row fits, the most specific row wins. This applies within a group or +between multiple. + +Per rule 4, every type updates alongside what it describes. Four types carry their own cadence +besides: runbooks re-verify on every execution, changelogs update every release, RCAs follow the +incident process, and team process pages are at the owning team's discretion. + +A type not listed here is routed with the [decision rule](#decision-rule) and then added, by PR, to +the group matching its home. If the rule does not route it cleanly, that is a bug in this standard: +propose the fix and the new row in the same PR. + +#### In the repo + +| Documentation type | Home | Format | +| ------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------- | -------------------------------------------------- | +| Component docs: what one library, crate, or feature does and how to use it | `README.md` (or the component's `docs/`) next to the code | [Component documentation][component-docs] | +| Guides spanning multiple components in one repo | `docs/` or README at the components' lowest common ancestor | [Component documentation][component-docs] | +| Architecture of one repo | The owning scope's `docs/` or README | [Component documentation][component-docs] | +| Repo overview, build entry point | Root `README.md` | The [bitwarden/template][template] README skeleton | +| New-repo doc scaffolding (README skeleton, CONTRIBUTING pointer, `.claude/`) | [bitwarden/template][template] | — | +| Repo-specific code style overrides (coupled to lint/formatter config) | Repo `docs/`, linking the org baseline | — | +| API / SDK reference | Doc comments in source | [Component documentation][component-docs] | +| UI component library usage docs (audience: developers **and** designers) | `.mdx` colocated with the UI component, rendered at [components.bitwarden.com][storybook] | Storybook `autodocs` | +| Changelog for a published artifact | `CHANGELOG.md` next to the artifact | Ecosystem convention | +| Platform-mandated files (`SECURITY.md`, `.github` templates, `CODEOWNERS`, registry READMEs, store metadata) | Path fixed by the platform | Platform-defined | +| Legal, licensing, and trademark notices | Repo root | — | + +#### On contributing.bitwarden.com + +| Documentation type | Home | Format | +| -------------------------------------------------------------------- | ---------------------------------------------------------------- | -------------------------------------- | +| Contribution how-to, environment setup, org-wide code style | contributing.bitwarden.com › Contributing | — | +| Org-wide engineering standards (this standard, AI review guidelines) | contributing.bitwarden.com › Contributing | — | +| Architecture decision records | [contributing.bitwarden.com › Architecture › ADRs][adr-index] | Template on the [ADR index][adr-index] | +| Architecture spanning repos | contributing.bitwarden.com › Architecture | — | +| Deep dives (cross-repo or conceptual) | contributing.bitwarden.com › Architecture › Deep Dives | — | +| Security principles & requirements | [contributing.bitwarden.com › Architecture › Security][security] | — | + +#### In private locations + +| Documentation type | Home | Format | +| ------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------- | +| Runbooks, on-call, operational docs | Confluence, owning **team** space | [Runbook template][runbook-template]Runbook template (internal) | +| Incident post-mortems / RCAs | incident.io → Confluence export (IP space only) | incident.io process | +| Infrastructure and deployment architecture | Confluence, owning team space | — | +| Production change records | Confluence, owning team space | — | +| Team & org process: planning, assessments, investigations, onboarding and hiring, directories, working groups | Confluence team space | — | +| Tech breakdowns / work specifications | [bitwarden/tech-breakdowns][tech-breakdowns]bitwarden/tech-breakdowns (private repo) | — | + +[component-docs]: ./component-documentation.md +[runbook-template]: ./runbook-template.md +[template]: https://github.com/bitwarden/template +[storybook]: https://components.bitwarden.com +[adr-index]: ../../architecture/adr/index.mdx +[security]: ../../architecture/security/index.mdx +[tech-breakdowns]: https://github.com/bitwarden/tech-breakdowns + +## Audience (rule 3) + +Documents without a targeted audience lack focus. Even if the original author had a specific +audience in mind, the living and collaborative nature of our documentation makes an explicit +audience callout necessary. Apart from ADRs, every isolated (not directly attached to code) document +MUST include an audience the document is written for. + +## Documentation updates (rule 4) + +The only thing that is worse than missing documentation is inaccurate documentation. It misinforms, +wastes time, and frustrates. This standard is designed to maximize the amount of documentation that +can be kept in lock-step with the code it describes, and the **doc-parity plugin**, which every repo +MUST adopt from [bitwarden/ai-plugins](https://github.com/bitwarden/ai-plugins), enforces it: at +agent execution time for in-repo docs, and at review time for external docs. When a change +invalidates an external doc, a work item MUST be created before merge and the doc MUST receive a +[stale marker](#stale-markers) at the same time. The work item is done when the marker comes off, +and prioritization belongs to the owning team. Finally, the PR checklist item "Updated any necessary +documentation" reminds the PR author to update docs, and the reviewer validates it like code. + +### Deleting is maintenance + +When code is removed, remove its docs. Moving or replacing a doc is a **strict move**: the old +location MUST be deleted and known inbound links MUST be updated. ADRs are the exception: they are +historical records, so their supersession is a status change with a link to the successor, never a +deletion. + +Similarly, when decisions or trends change, docs MUST be updated to reflect the new reality. +Documents MUST NOT maintain a historic record of prior thinking, breadcrumb artifacts of the path to +the current state, or tedious enumerations of prior misunderstandings. + +### Stale markers + +Documentation known to be outdated but not yet fixable gets a top-of-file banner: +`⚠️ Outdated (YYYY-MM-DD): , per . Fix tracked by .` +Stale documentation is worse than none because it confidently misleads. Make inaccuracies known, +even when correction is not prioritized. + +### Owners + +Ownership follows `CODEOWNERS` for in-repo docs. Confluence pages name an owning team in the header +and SHOULD follow the owners of the Confluence space. + +Owners are responsible for the maintenance and general health of the documentation they own. + +### Changes to this standard + +A change to this standard that current reality violates ships with a remediation path in the same +change. This means tracked work items where the violations are enumerable, or a transition plan +(owned migrations, convert-on-touch policies, tracked deviations) where they are not. Existing +violations are named, never silently grandfathered. + +## Style guide (rule 5) + +Match form to content: walkthroughs and deep dives are prose, while reference material leans on +tables, lists, and rules. Both are legitimate. Code comments follow language norms +([Component documentation](./component-documentation.md)). + +- **Docs have a default entry point**: the index for Confluence and contributing.bitwarden.com, the + README for code repos. +- **Diagrams follow the [diagram standard](./diagrams.md)**. +- **Concise, single-purpose.** Sprawling documentation is hard to maintain and a chore to consume. + Write the minimum that serves the audience, and delete what does not. +- **Highly linked.** Link to supporting and related docs, since linking is what enables concise, + single-purpose documents. + - Say what is behind the link ("the ADR index explains statuses", not "see here"). + - Relative links within a repo, full URLs across repos and sites. + - Public pages MUST NOT link to internal-only destinations outside a `` gate, since + external contributors cannot access them. +- **Lead with the point.** Open with what the reader came for: what the component does, how the flow + works, the takeaway. Background, rationale, and edge cases follow. +- **Sentence case** for all headings ("Considered options", not "Considered Options"). +- **Headings mark lookup targets.** Add one where a reader would search or deep-link, never to break + up text. +- **Procedures** are numbered steps starting with a verb ("Run…", "Open…", "Set…"). One command per + fenced code block, never inline, always with a language tag. State expected output when it is not + obvious. +- **Code samples are real**: taken from or verified against the actual codebase, with file paths + (`libs/state/README.md` style). +- **No invented shorthand.** Spell out space, section, and product names. A reader should not need + to decode abbreviations the document never defines. +- **Formatting is tooling's job**: Prettier and cspell where the repo has them. Repos SHOULD adopt + both plus a link checker in CI. + +### Standards documents + +Normative documents like this one (org-wide standards, the diagram standard) carry additional +formality, since readers and tooling act on their exact wording: + +- **RFC 2119 keywords** in all caps mark requirement levels. Define them, and any other notation the + document relies on, in a [Notation](#notation) section up front. +- **Lead with the rules**: a numbered rule list up top, elaboration sections tagged by the rules + they explain. +- **Rationale rides in a trailing `:::note`** whose numbering matches the rules, as the + [decision rule](#decision-rule) does, or attaches with "since" or "because". No em-dash, + parenthetical, or semicolon asides, and no asides that only dramatize a rule. +- **No contractions.** Write "do not", "cannot", and "it is" in full. + +## Definition of done + +A documentation change (or the doc portion of a code change) is done when it satisfies +[the standard](#the-standard) and the [style guide](#style-guide-rule-5). + +For a **code** change, every README, `docs/` page, diagram, doc comment, and `CLAUDE.md` that +describes the changed behavior MUST be updated in the same PR. If none described it but it warrants +documentation per the [component README standard](./component-documentation.md), add it. diff --git a/docs/contributing/documentation/runbook-template.md b/docs/contributing/documentation/runbook-template.md new file mode 100644 index 000000000..f355108b2 --- /dev/null +++ b/docs/contributing/documentation/runbook-template.md @@ -0,0 +1,83 @@ +--- +sidebar_position: 3 +sidebar_custom_props: + access: bitwarden +--- + +# Runbook template + + + +**Audience:** Bitwarden engineers authoring or executing runbooks. + +Notation follows the [documentation standard's Notation](./index.md#notation). + +This template produces Confluence pages in the owning team's space, under that space's runbook +index, never in a personal space. The structure below maps 1:1 to Confluence headings, and the +metadata block is a table at the top of the page. + +````markdown +# Runbook: (e.g., "Rotate data protection certificate") + +| | | +| -------------------- | ------------------------------------------------------- | +| **Owner** | (Slack: #) | +| **Audience** | | +| **Service / system** | | +| **Last verified** | YYYY-MM-DD by | +| **Supersedes** | | +| **Risk** | | + +## Notation + + + +## When to use this + +One or two sentences: the alert, symptom, or scheduled task that triggers this runbook. If there is +a related incident type or Datadog monitor, link it. + +## Prerequisites + +- Access needed (roles, groups, VPN, break-glass); link the request path. +- Tools needed and where to get them. +- Preconditions to confirm before starting (and how to confirm them). + +## Steps + +1. Verb-first instruction. + + ``` + one command per code block + ``` + + Expected output: . + +2. **⚠️ point of no return** Next step. Call out irreversible steps before the step, not after as + done for this step. + +## Verification + +How to confirm the overall operation succeeded before closing the page. + +## Rollback + +How to undo, or the explicit statement "not reversible past step N; escalate instead." + +## Escalation + +Who to page/ask when a step fails, in order (person/rotation, Slack channel, incident.io severity to +raise). +```` + +Rules: + +- **Last verified** is updated by whoever executes the runbook, every time; fixing drift found + during execution is part of executing. If not verified in 12 months, add a + `⚠️ Unverified since ` banner. +- One command per code block; no prose-embedded commands, since responders copy-paste under + pressure. +- When this runbook replaces another, delete the old page after updating known inbound links. +- Diagrams, if any, follow the [diagram standard](./diagrams.md). + +