Files
docs/reference/foundations/Documentation Styling.md
T
nicole bec6542ee7
Automatic Documentation Deployment / Sync Docs to https://kb.bunny-lab.io (push) Successful in 3s
Update reference/foundations/Documentation Styling.md
2026-07-11 13:24:13 -06:00

2233 lines
85 KiB
Markdown

---
tags:
- Documentation
- Markdown
- Style Guide
- AI Agents
---
## Purpose
This document defines the **authoritative Markdown documentation contract** for the Bunny Lab knowledgebase. It exists so that ChatGPT, Codex, automation tools, and human contributors can create or revise documentation without replacing the established Bunny Lab style with generic technical-writing conventions.
This standard governs the Markdown source itself, including front matter, page openings, headings, section order, prose, spacing, lists, links, admonitions, code fences, content tabs, code annotations, tables, diagrams, validation, troubleshooting, and document-type templates.
!!! info "Scope"
This document applies only to Markdown documentation. Theme implementation, CSS, JavaScript, site appearance, and other presentation-layer concerns are outside the scope of this standard.
## Authority and Rule Precedence
The words **MUST**, **SHOULD**, and **MAY** are used deliberately:
- **MUST** identifies a required house-style rule.
- **SHOULD** identifies the normal Bunny Lab default unless the document has a concrete reason to differ.
- **MAY** identifies an optional pattern that is already compatible with the documentation style.
When instructions conflict, use the following precedence:
- The user's explicit request for the current task
- Technically correct and safe procedure content
- This documentation standard
- The established local pattern in the document being edited
- The established pattern in adjacent documents of the same type
Technical correctness and operator safety always outrank visual consistency. Do not preserve a typo, malformed Markdown construct, unsafe command, stale fact, broken link, or misleading statement merely because it already exists in the repository.
## Core Documentation Identity
Bunny Lab documentation is written for a technically capable operator who understands the underlying technology but does not automatically know the local environment, prior decisions, hidden prerequisites, or the reason a particular implementation was chosen.
The documentation SHOULD be:
- Operational and directly usable
- Explicit about where, when, and as whom a command must be run
- Reproducible from the page alone
- Honest about homelab-specific assumptions and risk tolerance
- CLI-first when the CLI is the clearer or more deterministic interface
- GUI-explicit when a WebUI is the actual or more practical control plane
- Detailed around dangerous, stateful, or non-obvious operations
- Concise around routine concepts an experienced operator already understands
- Written in a direct, recognizable Bunny Lab voice rather than sterile enterprise boilerplate
The governing principle is:
> Assume technical literacy, but never assume local knowledge.
## One Primary Intent per Document
Every page MUST have one primary content type and one primary intent:
- **Deployment** — builds or installs a platform, service, or automation stack
- **Workflow** — performs maintenance, migration, recovery, troubleshooting, or another day-2 operation
- **Script** — preserves a reusable script, command sequence, or operational utility
- **Reference** — records stable facts, architecture, inventory, mappings, concepts, or standards
- **Index** — introduces a folder and describes the content grouped beneath it
- **Blog** — records narrative experience, experimentation, lessons learned, or opinion
Do not combine unrelated deployment, workflow, script, and reference concerns into a single page merely because they involve the same product. Split independent intents into separate pages and connect them with descriptive links.
## House Style at a Glance
| **Area** | **Bunny Lab Standard** |
| :--- | :--- |
| Normal page title | Derived from the Markdown filename; do not duplicate it with an H1 |
| Index and blog title | One explicit H1 matching the page or post title |
| Normal page opening | Front matter, one blank line, then `## Purpose` |
| Major structure | `##` headings for major phases or topics |
| Substructure | `###` headings for actions within the current phase |
| Deep nesting | `####` only when a genuinely complex subsection requires it |
| Paragraph source layout | One physical source line per paragraph; do not hard-wrap prose |
| Sentence spacing | Two spaces after sentence-ending punctuation when another sentence follows on the same source line |
| Block spacing | One blank line between Markdown blocks; no blank line between a heading and its first content block |
| Bullet marker | Hyphen (`-`) |
| Nested indentation | Four spaces per nesting level; never tabs |
| Procedures | Action-oriented headings and bullets; avoid manually numbered top-level steps |
| Code fences | Fenced, language-tagged, copy/paste-ready, and grouped by execution context |
| Fence syntax | No space between the opening backticks and language identifier |
| Admonitions | Sparse, titled when the title adds meaning, and placed before the affected action |
| Diagrams | Plain-text hierarchy or Mermaid, selected according to the information being explained |
| Voice | Direct second person, operational transitions, and limited first-person lab context |
| Validation | Explicit for risky or state-changing work; include the command or observable success condition |
## Markdown Source Formatting
### File Encoding and Line Endings
Markdown files MUST use UTF-8 text, consistent line endings, and a final newline at end of file.
Do not introduce tabs for indentation. Use spaces only.
### Paragraph Layout
Each prose paragraph MUST remain on one physical source line, even when the rendered paragraph is long. Do not manually wrap prose at 80, 100, or 120 columns.
Use a blank line to create a new paragraph. Do not create a new source line merely because the next sentence begins.
Correct:
```markdown
This procedure expands the backing storage first. The guest operating system is updated only after the hypervisor reports the new capacity.
```
Incorrect:
```markdown
This procedure expands the backing storage first. The guest operating
system is updated only after the hypervisor reports the new capacity.
```
### Sentence Spacing
When two sentences occur in the same paragraph, use **two spaces** after the sentence-ending period, question mark, or exclamation point.
Correct:
```markdown
The target must be reachable before continuing. If discovery returns no targets, stop and correct networking first.
```
Do not add two spaces after commas, colons, semicolons, abbreviations, decimal points, or periods inside hostnames and version numbers.
### Blank Lines
Use exactly one blank line between separate Markdown blocks, including paragraphs, lists, admonitions, tables, diagrams, and fenced code blocks.
Place one blank line **before** a heading unless the heading is the first body element after front matter or an immediate child heading directly beneath its parent. Do not place a blank line between a heading and its first paragraph, child heading, list, admonition, table, tab set, or code block.
Correct:
````markdown
## Configure the iSCSI Target
Run the following commands on the TrueNAS Core server.
```sh
service ctld start
sysrc ctld_enable=YES
```
## Validate the Listener
```sh
sockstat -4l | grep ':3260'
```
````
Do not insert multiple blank lines to simulate spacing. Source structure, not extra blank lines, separates ideas.
### Trailing Whitespace and Hard Breaks
Do not leave trailing spaces at the end of source lines. Do not rely on two trailing spaces to force a Markdown line break.
Use a paragraph break, list, table, or explicit structural element instead.
### Horizontal Rules
Horizontal rules are not routine section separators. Headings already provide document structure.
Use `---` in the body only when a landing page, disclaimer page, or unusually long document needs a deliberate major visual boundary. Do not place a horizontal rule after every section.
## Front Matter
### Standard Documentation Pages
Normal deployment, workflow, script, reference, and folder index pages MUST begin with YAML front matter containing a `tags` list. The special root `index.md` landing page is the deliberate exception described later in this standard.
```yaml
---
tags:
- Proxmox
- iSCSI
- Storage
---
```
The closing `---` MUST be followed by one blank line.
Normal documentation pages SHOULD contain only the `tags` key unless another key is required by an established content feature. Do not add `title`, `description`, navigation position, sidebar position, or hand-maintained navigation metadata to an ordinary page without a documented content requirement.
### Tag Selection and Order
Use between two and five meaningful tags. Three tags is the normal target.
Order tags from most specific to most general:
- Primary product, platform, or service
- Secondary technology, protocol, or task
- Broader domain or content category
- Script language or content type when applicable
Examples:
```yaml
---
tags:
- Active Directory
- Certificate Services
- Authentication
---
```
```yaml
---
tags:
- Veeam
- Backup
- Disaster Recovery
---
```
```yaml
---
tags:
- SSH
- Bash
- Authentication
- Scripting
- Linux
---
```
Use established product capitalization in tags. Do not create near-duplicate tags that differ only by capitalization, punctuation, abbreviation, or pluralization.
### Blog Front Matter
Blog posts use the following key order:
```yaml
---
draft: false
date: 2026-07-11
updated: 2026-07-11
authors:
- nicole
categories:
- General
tags:
- Blog
- Documentation
- AI Agents
---
```
Dates MUST use ISO `YYYY-MM-DD` format. Use `draft: true` while a post is intentionally unpublished, and change it to `false` only when the post is ready to publish. Update `updated` only when the post is materially revised.
An optional `links` list MAY appear after `authors` and before `categories` when the post has deliberately associated documentation pages. Contextual links in the body remain necessary when the relationship matters to the narrative.
The `Blog` tag SHOULD appear first. Categories remain broad, while tags identify the specific technologies or subjects discussed.
### Navigation Behavior
Navigation is filesystem-derived. Do not add hand-maintained navigation arrays or page ordering metadata to normal Markdown front matter.
Use `index.md` as the landing page for a folder that needs an introduction. Index pages describe the category at a high level; they do not need to reproduce the entire generated navigation tree as a manually maintained list.
## File Naming and Page Identity
### Ordinary Documentation Files
Use a human-readable filename that states the page subject without requiring an H1 inside the document. New deployment, workflow, script, and reference filenames SHOULD use Title Case with spaces while preserving exact product names and acronyms.
Prefer an action phrase for a procedural page:
- `Configure SSH Key Authentication.md`
- `Expand ISCSI Based ZFS Filesystem.md`
- `Deploy Failover Cluster Node.md`
- `Migrate VMs to ProxmoxVE.md`
Prefer a noun phrase for stable reference material:
- `Core Veeam Concepts.md`
- `Disk Arrays.md`
- `Homelab Server Inventory.md`
Avoid vague filenames such as `Notes.md`, `Misc.md`, `Setup.md`, or `Guide.md` when the subject can be named directly. Preserve an established lowercase product filename such as `traefik.md` during a targeted edit; do not create a rename-only diff unless the task includes link migration.
### Index Files
Use the exact lowercase filename `index.md` for a folder landing page. The folder name supplies the category identity, while the page H1 supplies the rendered title.
### Blog Post Files
Use the established blog filename form:
```text
MM-DD-YYYY Post Title.md
```
The filename date SHOULD match the initial publication date in front matter. The H1 inside the post MUST match the post title portion of the filename, preserving intentional capitalization.
### Renames
A filename change is a content migration, not a cosmetic edit. When renaming a page, update every inbound relative link and any stable heading anchors affected by the move. Do not rename files as an incidental part of an unrelated technical correction.
## Page Titles and Heading Hierarchy
### Ordinary Documentation Pages
Ordinary deployment, workflow, script, and reference pages MUST omit an H1 unless the page is a deliberately self-contained proposal or report. The repository uses the Markdown filename and filesystem-derived navigation as the title convention for ordinary operational pages.
After front matter, begin immediately with `## Purpose`. The Purpose section is the first body element on every ordinary deployment, workflow, script, and reference page.
!!! warning "Do Not Duplicate the Filename as an H1"
Do not add `# Deploy Service Name` to a normal page solely because a generic Markdown style guide recommends one H1 per file. Bunny Lab operational pages normally begin below the page-title level.
### Pages That Use an H1
Use exactly one H1 for:
- Root and folder `index.md` landing pages
- Blog posts
- A deliberately self-contained proposal or report whose visible title is part of the content
The H1 MUST match the intended page title and MUST appear immediately after front matter when front matter is present. The special root `index.md` landing page may begin directly with `# Home`.
### Heading Levels
Use heading levels according to document function:
- `##` — major phase, major topic, or top-level document section
- `###` — action, component, method, or subsection within the current `##`
- `####` — tightly scoped subprocedure inside a complex `###`
Do not use H5 or H6 in normal documentation. If a page requires that depth, the structure is probably over-fragmented or contains more than one primary intent.
Do not skip levels in new or substantially rewritten content. A `####` must belong beneath a `###`, and a `###` must belong beneath a `##`.
### Heading Wording
Use concise Title Case for headings while preserving exact product names, command names, acronyms, paths, and inline code.
Prefer action-oriented procedural headings:
- `## Configure Shared LVM`
- `### Create the Zvol`
- `### Validate the iSCSI Listener`
- `## Expand the GuestVM Filesystem`
- `### Rebuild the Replica Database`
Use descriptive noun headings for reference material:
- `## Architecture`
- `## Assumptions`
- `## Environment Variables`
- `## Disk Layout`
- `## Troubleshooting`
Do not end headings with a period. Avoid trailing colons unless the colon is part of an exact quoted label.
Write `and` rather than `&` unless an ampersand is part of an official product name or exact UI label. Parenthetical scope such as `(One Node Only)` or `(Ubuntu Server)` is acceptable when it prevents ambiguity.
Do not use emoji or decorative icon shortcodes in ordinary operational headings. The root landing page and blog posts MAY use them sparingly when they are part of the intended presentation.
### Phase Labels
Do not number routine procedural headings. The page is read top to bottom, and heading order communicates sequence.
A high-risk or very long runbook MAY use explicit phase labels when they improve operator state awareness:
```markdown
## Phase 1: Audit Existing Volumes
## Phase 2: Confirm References Across the Cluster
## Phase 3: Remove Verified Orphans
```
Phase headings remain at `##`; do not promote each phase to a new H1.
## Purpose Sections
### Required Form
Every deployment, workflow, script, reference, and folder index page MUST use an H2 Purpose heading written exactly as:
```markdown
## Purpose
```
Do not use a bold `Purpose` label, an H1 Purpose heading, or a trailing colon. A short page still uses `## Purpose`; brevity does not justify a different opening form.
On an ordinary documentation page, `## Purpose` appears immediately after front matter. On a folder index page, it appears immediately after the page H1. Blog posts and the special root landing page follow their own contracts and do not require a Purpose section.
### Purpose Content
A Purpose section SHOULD identify:
- What the document accomplishes
- Why the operation, configuration, script, or reference exists
- The environment or implementation to which it applies
- The starting state when that state materially affects the procedure
- The success state or important limitation that defines completion
A substantial page may use two or three connected paragraphs and a short scope list. A small script or one-liner may use one sentence. In both cases, the heading remains `## Purpose`.
```markdown
## Purpose
This document describes how to expand an iSCSI-backed ZFS filesystem presented to a Linux GuestVM. The procedure expands each storage layer in dependency order and validates the usable capacity before moving to the next layer.
```
Do not turn Purpose into a generic product description copied from a vendor page. Connect the technology to its actual Bunny Lab role, operational need, or local implementation.
### Purpose Opening Patterns
Purpose text often begins with the operator's situation or desired result rather than an abstract definition. The following openings are compatible with the Bunny Lab voice:
- `You may find that you need to ...`
- `Sometimes you need to ...`
- `When you need to ...`
- `This document outlines ...`
- `This document serves as a general guideline for ...`
- `The purpose of this workflow is to illustrate ...`
- `In my homelab, ...`
Choose the opening that naturally fits the page. Do not force every Purpose section to begin with the same formula.
For a service deployment, a one-sentence product description is acceptable when it is immediately connected to the local role or deployment objective. Avoid copying a vendor's marketing paragraph without explaining why the service exists in Bunny Lab.
## Document Flow and Section Order
Bunny Lab documentation assumes the operator reads from top to bottom and acts within the current section. Section order is intentional and normally replaces explicit step numbering.
Use the following general flow when the content requires each element:
- Purpose
- Assumptions, prerequisites, risk boundaries, or version context
- Architecture, terminology, variables, inputs, or dependencies
- Action-oriented deployment or workflow sections
- Validation at meaningful checkpoints and at completion
- Troubleshooting and known failure modes
- Rollback, recovery, cleanup, or follow-up work
- Reference documentation
Do not force every heading into every page. A five-line command reference does not need architecture, rollback, and troubleshooting sections. A storage migration that can destroy data does.
Do not append a generic `## Summary` or `## Conclusion` to every page. Add one only when a complex document genuinely benefits from a final synthesis, decision record, or operator handoff.
Prefer specific action headings over a generic `## Procedure` heading. `## Procedure` is acceptable only when the page is so short that a more specific heading would repeat the page title.
## Document-Type Contracts
### Deployment Documents
A deployment page explains how to build or install a platform, service, or automation system.
A substantial deployment SHOULD contain:
- `## Purpose`
- Assumptions or prerequisites immediately after Purpose
- Architecture or dependency context when multiple systems interact
- Major deployment phases as `##` headings
- Component-level actions as `###` headings
- Configuration files in titled code blocks
- Initial-access or onboarding instructions when applicable
- Validation that proves the service is available and correctly integrated
- Troubleshooting or rollback when failure has meaningful consequences
Keep commands grouped by execution context. Clearly state when work moves from one server, node, shell, account, or WebUI to another.
### Containerized Service Deployments
A compact Docker or Portainer service page commonly follows this sequence:
- `## Purpose`
- Optional vendor reference link
- Important pre-deployment warning or assumption
- `## Docker Configuration`
- `docker-compose.yml` block
- `.env` block when variables are used
- `## Traefik Reverse Proxy Configuration` when applicable
- Initial login, onboarding, or validation notes when applicable
Do not include an empty `.env` block containing `Not Applicable`. Omit the block when no environment file is required.
Do not add a reverse-proxy section automatically. Include it only when the documented deployment actually uses a reverse proxy.
### Workflow Documents
A workflow is a day-2 runbook, maintenance procedure, migration, repair, recovery, or troubleshooting process.
A workflow SHOULD contain:
- `## Purpose`
- Assumptions, scope, and the starting state
- A warning or danger admonition before irreversible work
- Action-oriented headings in execution order
- Explicit system or node context before commands
- Validation after each state transition that must succeed before continuing
- Final validation
- Rollback or recovery when an operation can leave the environment degraded
Do not hide the point of no return. State it immediately before the destructive command or commitment action.
### Script Documents
A script page preserves executable content and enough context to run it safely.
A script page SHOULD contain:
- `## Purpose`
- Requirements, privileges, modules, or supported operating systems when not obvious
- Variables or parameters the operator must change
- `## Script` or a language-specific heading such as `## PowerShell Script`
- A correctly fenced complete script
- `## Usage` with a copy/paste-ready example when the invocation is not self-evident
- Expected output, created files, side effects, and destructive behavior
- Notes for edge cases or known limitations
A one-liner MAY consist of front matter, `## Purpose`, one concise purpose sentence, and one code block.
### Reference Documents
A reference page records information rather than walking the operator through a single state-changing task.
Reference pages MAY contain:
- `## Purpose`
- `## Scope`
- Architecture or terminology
- Tables, inventories, mappings, addresses, disk layouts, variable definitions, or decision matrices
- Maintenance notes describing how and when the reference must be updated
- Links to the workflows or deployments that consume the reference
Do not force validation or troubleshooting sections into static inventory pages.
### Index Pages
Every first-level and important second-level folder SHOULD have an `index.md` landing page.
An index page uses:
- Standard tags front matter
- One H1 matching the folder/category name
- `## Purpose`
- `## Includes` with a concise list of content classes grouped beneath the folder
Do not hand-maintain a complete list of every child page unless the index itself is intentionally a curated catalog. Generated navigation remains the source of truth for page discovery.
Do not embed new copies of the documentation templates in multiple index pages. This document is the single authoritative template source, and duplicated templates will drift.
### Blog Posts
Blog posts intentionally use a more personal and narrative voice than operational documentation.
A blog post uses:
- Blog front matter
- One H1 matching the post title
- An opening paragraph that establishes context
- `##` headings for major parts of the story or analysis
- `###` headings only when a major section genuinely needs subdivision
- First-person observations, opinions, lessons learned, and uncertainty when appropriate
- Technical blocks, tables, links, diagrams, and admonitions when they support the narrative
Do not rewrite a blog post into impersonal runbook language.
## Voice and Tone
### Primary Voice
Use direct second-person language for operator actions:
- `You will need to run this command on every ProxmoxVE node.`
- `Navigate to "**Datacenter > Storage > Add > LVM**".`
- `If discovery returns no targets, stop and verify the portal address.`
- `You will know the deployment is ready when every pod reports a Running status.`
Imperative sentences are also appropriate:
- `Create the deployment directory.`
- `Restart the service.`
- `Validate the new capacity before continuing.`
### Shared Process Voice
Use `we` sparingly to guide the operator through a transition:
- `At this point, we need to rescan the block device before expanding the physical volume.`
- `Now we can register the storage in ProxmoxVE.`
Do not use `we` in every paragraph. The reader remains the person performing the work.
### First-Person Lab Context
Use first person when the statement is specifically about Nicole's environment, preference, test result, or implementation decision:
- `In my lab environment, the partition table did not refresh until the server was rebooted.`
- `I use a dedicated Docker MACVLAN network for these containers.`
- `In my lab, I keep the Root CA offline except when publishing a new CRL.`
First person should explain local context, not narrate every keystroke.
### Recognizable Transitional Language
The following transitions are compatible with the established style when used naturally:
- `At this point, ...`
- `Now you need to ...`
- `Once this is complete, ...`
- `If this happens, ...`
- `You will know this worked when ...`
- `In this example, ...`
- `For the purposes of this document, ...`
Do not repeat the same transition at the start of every section.
### Explaining Concepts and Decisions
When a concept requires more than an imperative command, explain it in the following order:
- Identify the current state, object, or problem
- Explain the mechanism or dependency that matters
- State the operational consequence
- Move into the action or validation the operator needs to perform
A typical Bunny Lab paragraph connects those ideas directly:
```markdown
The iSCSI extent exposes the zvol to every ProxmoxVE node, but the shared volume group does not automatically consume newly added capacity. This means the block device must be rescanned before the physical volume can be resized. At this point, run the rescan on every node and perform `pvresize` on one node only.
```
Two to four connected sentences in one paragraph are acceptable when they explain cause, effect, and the next action. Do not reduce every explanation to isolated bullets, and do not separate the reason from the command it governs.
### Contractions and Parenthetical Context
Natural contractions such as `you'll`, `don't`, `it's`, and `can't` are acceptable in explanatory prose when they match the surrounding voice. Use uncontracted safety language such as `do not`, `must not`, and `cannot` when a boundary needs to be unmistakable.
Parenthetical context MAY clarify an example, version difference, lab-specific observation, or likely exception. Do not hide a required command, prerequisite, warning, or success condition inside parentheses.
### Explanatory Depth
Explain:
- Why a dangerous or unusual action is required
- Why order matters
- Why a specific node or account must perform the action
- What state change the command causes
- What output proves success
- What failure looks like and when the operator must stop
- Which parts are homelab-specific or intentionally less secure
Do not explain routine concepts that the intended operator already knows unless the explanation prevents a likely mistake.
### Tone Boundaries
The tone is conversational and practical, but not casual to the point of ambiguity.
Avoid:
- Marketing language copied from product pages
- Corporate filler and generic enterprise boilerplate
- Fake certainty or unverified claims
- Long narrative detours in operational pages
- Artificially formal phrases such as `the user shall now proceed`
- Generic AI phrases such as `In today's rapidly evolving landscape`
- Repeated statements that an action is easy, simple, obvious, or straightforward
- Mimicking historical spelling errors, punctuation mistakes, or malformed Markdown
Correct grammar, spelling, and technical capitalization while preserving the Bunny Lab voice.
## Preferred Terminology and Capitalization
Use official names where they are established, while retaining the recurring Bunny Lab compounds below.
| **Concept** | **Preferred Form** | **Notes** |
| :--- | :--- | :--- |
| Command-line interface | `CLI` | Use uppercase |
| Graphical interface | `GUI` | Use uppercase |
| Web interface | `WebUI` | Established Bunny Lab form |
| Guest virtual machine | `GuestVM` | Established Bunny Lab form |
| Proxmox product | `ProxmoxVE` | Established Bunny Lab prose form; command and configuration names remain exact |
| Microsoft hypervisor | `Hyper-V` | Preserve hyphen |
| Microsoft shell | `PowerShell` | Capitalize in prose and headings |
| iSCSI protocol | `iSCSI` | Preserve lowercase `i` |
| IP security | `IPSec` | Use consistently within a page |
| Docker configuration system | `Docker Compose` | Use `docker-compose.yml` for the filename when that is the actual file |
| Fully qualified domain name | `FQDN` | Use uppercase |
| Knowledge environment | `homelab` | Lowercase unless it begins a sentence or heading |
| Configuration language | `YAML` | Uppercase in prose; use `yaml` as the fence identifier |
| Operating system | `OS` | Use uppercase |
| Virtual machine | `VM` | Use uppercase |
Do not change literal command names, service names, paths, variables, registry keys, configuration keys, or vendor-provided identifiers to match prose capitalization.
## Lists
### Bullet Lists
Use hyphens for unordered lists.
```markdown
- ProxmoxVE nodes can reach the iSCSI portal
- The backing ZFS pool is healthy
- All affected workloads are drained
```
Indent nested bullets by four spaces:
```markdown
- Navigate to "**Server Manager > Manage > Add Roles and Features**"
- Select "**Active Directory Certificate Services**"
- Click "**Add Features**"
```
Do not mix `-` and `*` bullet markers within a page.
### List Punctuation
Use no terminal punctuation for short fragments. Use periods when list items are complete sentences or contain multiple sentences.
Keep parallel grammatical form within the same list. If the first item begins with an imperative verb, the remaining items SHOULD do the same.
### Numbered Lists
Do not use manually numbered lists as the default structure for procedures. Headings and top-to-bottom order already communicate sequence.
Numbered lists are appropriate for:
- Code annotations tied to markers such as `(1)` and `(2)`
- A decision sequence where the numeric identity is referenced later
- A formal migration plan or ordered phase list
- A set of questions whose numbering matters
Do not write `Step 1`, `Step 2`, and `Step 3` when `##` and `###` action headings communicate the same structure more clearly.
### Task Lists
Use task lists only when the page is intentionally providing an operator checklist, preflight gate, migration acceptance list, or destructive-action confirmation list.
```markdown
- [ ] Confirm the active replica is healthy
- [ ] Confirm a current backup exists
- [ ] Confirm the target volume is not referenced by any GuestVM
```
Use hyphens, lowercase `x` for checked items, and one space inside an unchecked box. Do not use task lists as a decorative replacement for normal bullets or as the default structure for a procedure. A published runbook normally leaves operator-executed checkboxes unchecked.
## GUI and WebUI Procedures
GUI-based instructions are valid when the product's WebUI is the actual administrative control plane or when the GUI makes the operation safer and clearer than an undocumented API or fragile CLI workaround.
### Navigation Paths
Represent a GUI path inside bold quotation marks and separate levels with `>`:
```markdown
Navigate to "**Datacenter > Storage > Add > LVM**".
```
Use the labels exactly as they appear in the interface. Preserve capitalization, punctuation, and product terminology.
### Click-Through Procedures
Use nested bullets for wizard and menu sequences:
```markdown
- Navigate to "**Storage > Pools**"
- Open the gear menu for the target pool
- Click "**Status**"
- Open the "**...**" menu for the failed disk
- Click "**Offline**"
```
Do not describe every `Next` click unless the screen boundary, setting, warning, or resulting state matters. When a wizard contains important defaults, document them explicitly.
### Field Values
Use a table when the operator must populate several form fields:
```markdown
| **Field** | **Value** |
| :--- | :--- |
| Storage ID | `iscsi-cluster-lvm` |
| Volume Group | `vg_proxmox_iscsi` |
| Content | `Disk image, Container` |
| Shared | Enabled |
```
### CLI and GUI Together
A page MAY use a hybrid workflow. State the boundary clearly:
- Use the CLI for reproducible creation, inspection, and validation
- Use the GUI for product-native objects or workflows that are safer there
- Do not mix GUI-managed and CLI-managed state when the product treats them as separate ownership models
When GUI and CLI are equivalent alternatives, use content tabs. When both are sequentially required, use normal sections instead.
## Code Blocks
Code blocks are a primary instructional vehicle and MUST be executable, readable, and correctly scoped.
### Universal Code-Fence Rules
Every code or output block MUST:
- Use a fenced block
- Include the most accurate language identifier available
- Use no space between the opening backticks and the language identifier
- Contain copy/paste-ready content unless the block is explicitly labeled as pseudocode or example output
- Preserve the syntax, indentation, quoting, and line continuations required by the target interpreter
- Be separated from surrounding prose by one blank line, except when it is the first block immediately after a heading
Correct:
````markdown
```sh
apt update
apt install -y open-iscsi lvm2
```
````
Incorrect:
````markdown
``` sh
apt update
```
````
### Language Identifiers
Use the following fence identifiers:
| **Content** | **Fence** |
| :--- | :--- |
| POSIX-compatible shell commands | `sh` |
| Bash-specific scripts or syntax | `bash` |
| PowerShell | `powershell` |
| Windows batch file | `batch` |
| Windows Command Prompt session | `cmd` |
| YAML | `yaml` |
| JSON | `json` |
| INI files and `.env` files | `ini` |
| Plain command output, diagrams, or untyped configuration | `text` |
| Markdown examples | `markdown` |
| Mermaid diagrams | `mermaid` |
Do not use `jsx` as a generic text or configuration fence. Use it only for actual JSX source code.
### Shell Fence Selection
Use `sh` for ordinary Linux or Unix command sequences that do not depend on Bash-only syntax.
Use `bash` when the block contains a Bash script, shebang, arrays, `[[ ... ]]`, process substitution, Bash-specific parameter expansion, or another Bash-only construct.
### Titled Code Blocks
Use `title="..."` when a block represents the complete or meaningful contents of a named file, path, registry location, task, or configuration artifact.
````markdown
```yaml title="docker-compose.yml"
services:
app:
image: example/app:latest
```
````
````markdown
```ini title=".env"
TIMEZONE=America/Denver
PUBLIC_FQDN=https://example.bunny-lab.io
```
````
````markdown
```bash title="/root/pve-storage-audit.sh"
#!/usr/bin/env bash
set -euo pipefail
```
````
Do not add titles to short command blocks merely for decoration.
### Command Grouping
Prefer one coherent block containing the commands for a single execution context and objective.
Use inline comments to identify internal phases:
```sh
# Install Required Packages
apt update
apt install -y open-iscsi lvm2
# Discover and Log In to the Target
iscsiadm -m discovery -t sendtargets -p <TRUENAS_IP>
iscsiadm -m node --login
# Validate the Block Device
lsblk
```
Split a block when:
- Commands run on different systems or nodes
- Commands require different shells or privilege contexts
- The operator must inspect output and make a decision before continuing
- A reboot, logout, or state transition occurs between command groups
- The next block is an alternative rather than a continuation
Do not create one-command-per-code-block sprawl.
### Command Context
Introduce the execution location before the block whenever it is not obvious:
````markdown
On `LAB-CA-01`, run:
```powershell
certutil -crl
```
````
Use explicit context phrases such as:
- Run this on every ProxmoxVE node.
- Execute the following on one cluster node only.
- From an elevated PowerShell session, run:
- As the `root` user on the TrueNAS Core server, run:
- In the AWX WebUI, navigate to ...
Do not bury one-node-only or every-node requirements after the commands.
### Shell Prompts
Do not include `$`, `#`, `PS C:\>`, or another shell prompt in a copy/paste command block.
A prompt MAY appear in a `text` block when reproducing authentic output or an interactive session, but commands and output must be clearly distinguishable.
### Comments Inside Code
Use concise comments to explain intent, execution boundaries, or values that must be changed.
Comments SHOULD describe why a group exists rather than paraphrasing every obvious command. Use one space after the comment marker. Use Title Case for standalone phase comments and normal sentence case for short inline comments.
Good:
```sh
# Preserve the Existing Configuration Before Replacing It
cp -av /etc/ctl.conf /etc/ctl.conf.$(date +%Y%m%d-%H%M%S).bak
```
Avoid:
```sh
# Run the cp command
cp file1 file2
```
### Placeholders
Use angle-bracket placeholders for values the operator must replace:
- `<TRUENAS_IP>`
- `<VM_NAME>`
- `<FQDN>`
- `<STORAGE_ID>`
- `<TARGET_DISK>`
Use uppercase snake case inside placeholders. Keep exact example values outside the placeholder when they materially help the operator.
Use `REDACTED` for a secret that existed in the original environment but must not be published.
Do not publish real passwords, API tokens, private keys, recovery codes, registration tokens, or other credentials.
### Commands and Output
Do not mix normal commands with their output in the same fenced block unless the block is explicitly an interactive transcript.
Use a `text` block for output:
````markdown
Expected output:
```text
LISTEN 0 128 0.0.0.0:3260
```
````
For long optional output, use a collapsible example admonition.
### Markdown Inside Markdown
When documenting Markdown that itself contains triple-backtick fences, wrap the example with four backticks:
`````markdown
````markdown
```sh
example-command
```
````
`````
## Code Annotations
Code annotations are an established Bunny Lab pattern for interactive command sequences, non-obvious parameters, and configuration values that need focused explanation.
Place a numbered marker in a code comment:
````markdown
```sh
pvcreate /dev/sdX # (1)
vgcreate vg_proxmox_iscsi /dev/sdX # (2)
```
1. Initializes the target block device as an LVM physical volume.
2. Creates the shared volume group used by ProxmoxVE.
````
Use two spaces after the annotation number, as shown in `1. Explanation`.
Annotation numbers MUST be sequential and MUST correspond exactly to markers in the preceding block.
Use annotations when the explanation is tied to a specific line. Use normal prose or code comments when the explanation applies to the whole block.
When annotations occur inside a content tab or admonition, indent both the code block and annotation list so they remain inside the parent structure.
## Admonitions
Admonitions are functional safety and context tools. They are not decoration.
### Standard Syntax
Use a lowercase admonition type and quote a custom title:
```markdown
!!! warning "Run on One Node Only"
Execute `pvresize` on exactly one ProxmoxVE node. The remaining nodes should only rescan the volume group after the resize is complete.
```
Indent all admonition content by four spaces. Do not place a blank line between the admonition declaration and its first content line.
Use one blank line before and after the complete admonition block.
### Admonition Types
| **Type** | **Use** |
| :--- | :--- |
| `abstract` | Concise architecture, deployment breakdown, or high-level model |
| `info` | Prerequisites, assumptions, version context, or supporting operational information |
| `note` | Important behavior, implementation context, or a detail the operator must retain |
| `tip` | Optional improvement, efficiency, or preferred practice |
| `warning` | Serious risk, stop condition, one-time decision, or action that can disrupt service |
| `danger` | Destructive or potentially data-losing action |
| `success` | Verified completion state or expected milestone |
| `example` | Example output, sample data, or an extended optional example |
| `bug` | Known product defect, inconsistent behavior, or reproducible failure |
| `failure` | A failed state and its meaning |
Use `question`, `quote`, `caution`, or custom types only when an existing page has a deliberate reason to preserve them. Do not invent custom admonition types for ordinary notes.
### Titles
A title SHOULD be concise, specific, and actionable:
- `"Run on One Node Only"`
- `"Do Not Proceed Until CRL Generation Works"`
- `"ProxmoxVE Version Context"`
- `"Snapshot Volumes Require Extra Caution"`
- `"Example Output"`
Avoid generic titles such as `"Important"` when a more specific title is available.
An admonition MAY omit a title when the type alone communicates the purpose and the content is only one short paragraph.
Do not use unquoted custom titles.
### Placement
Place a risk admonition **before** the command or GUI action it governs. Place a success admonition after the validation that proves the milestone.
Do not put the warning after the point of no return.
### Content Inside Admonitions
Admonitions MAY contain paragraphs, bullets, code blocks, and tables. Every nested block must remain indented by four spaces.
````markdown
!!! danger "Deleting the Replica Database"
This action destroys the replica copy and reseeds it from the active database. Confirm the active database is healthy before continuing.
```powershell
Update-MailboxDatabaseCopy -Identity "DB01\MX-DAG-02" -SourceServer "MX-DAG-01"
```
````
### Collapsible Admonitions
Use `???` for long optional details, verbose example output, or diagnostic scripts that would interrupt the primary workflow.
````markdown
??? example "Example Output"
```text
NAME READY STATUS RESTARTS AGE
awx-web 3/3 Running 0 2m
```
````
Do not collapse a warning, required command, prerequisite, or validation result that the operator must see before continuing.
## Content Tabs
Content tabs are an established Bunny Lab pattern for presenting peer material without duplicating surrounding context.
Use tabs for either of these purposes:
- **Mutually exclusive alternatives** — operating systems, GUI versus CLI, product versions, safe versus quick methods, filesystem types, or authentication methods
- **Peer configuration artifacts** — several complete files that belong to the same configuration stage, such as `awx.yml`, `ingress.yml`, `kustomization.yml`, `docker-compose.yml`, and `.env`
Do not use tabs for sequential phases that the operator must perform in order. Required preparation, execution, validation, and cleanup remain normal headings in top-to-bottom order.
### Alternative Tabs
Use stable, consistently capitalized labels so linked tabs behave predictably across pages.
````markdown
=== "Ubuntu Server"
```sh
sudo apt update
sudo apt install -y qemu-guest-agent
```
=== "Rocky Linux"
```sh
sudo dnf install -y qemu-guest-agent
```
````
Keep equivalent actions in the same order across alternative tabs. State which option is preferred when the choice has operational consequences.
### Peer File Tabs
Peer file tabs MAY group multiple files that are all required at the same stage:
````markdown
=== "awx.yml"
```yaml
<AWX_CUSTOM_RESOURCE>
```
=== "ingress.yml"
```yaml
<INGRESS_CONFIGURATION>
```
=== "kustomization.yml"
```yaml
<KUSTOMIZATION_CONFIGURATION>
```
````
Introduce the tab set with a sentence stating whether every file is required. A tab label that names a file does not replace a meaningful code-block title when the path itself matters.
### Tab Rules
- Quote every tab label.
- Put one blank line after the `=== "Label"` declaration.
- Indent every line of tab content by four spaces.
- Do not create a tab set containing only one tab.
- Do not use tabs to hide warnings, prerequisites, validation, or required follow-up work.
- Do not place unrelated systems or methods in one tab set merely to reduce page length.
- Do not split one command sequence across tabs when the commands must all be run.
## Tables
Use Markdown pipe tables for structured comparisons, field/value instructions, inventories, variable definitions, decision matrices, and expected states.
Use bold header text and alignment markers:
```markdown
| **Field** | **Value** | **Notes** |
| :--- | :--- | :--- |
| Storage ID | `iscsi-cluster-lvm` | ProxmoxVE storage identifier |
| Volume Group | `vg_proxmox_iscsi` | Shared LVM volume group |
| Shared | Enabled | Required for cluster visibility |
```
Use `---:` for right-aligned numeric columns when alignment materially improves readability.
Keep spaces between pipes and cell content. Use inline code for literal values, paths, identifiers, commands, ports, addresses, and configuration keys.
Do not use a table for a sequential procedure. Do not place several paragraphs in a table cell when normal sections would be easier to read and maintain.
## Diagrams
Diagrams MUST clarify architecture, sequence, ownership, hierarchy, or flow. Do not add diagrams as decoration.
### Plain-Text Diagrams
Use `text` for a compact hierarchy or storage stack:
```text
ZFS Pool
└─ Zvol
└─ iSCSI Extent
└─ LVM Physical Volume
└─ Shared Volume Group
└─ GuestVM Disks
```
### Mermaid Diagrams
Mermaid is an established Bunny Lab documentation format and SHOULD be used when relationships or sequence are clearer graphically.
Use:
- `sequenceDiagram` for service interactions, authentication, synchronization, and request flow
- `graph LR` for left-to-right operational flow
- `graph TB` for hierarchy, topology, or hub-and-spoke relationships
```mermaid
sequenceDiagram
actor Operator
participant ProxmoxVE
participant TrueNAS
Operator->>TrueNAS: Expand the backing zvol
Operator->>ProxmoxVE: Rescan the block device
ProxmoxVE-->>Operator: Report the new capacity
```
Place an architecture or flow diagram before the procedure it explains. Keep labels operational and concise. Avoid elaborate styling when the relationships alone communicate the required information.
ASCII-only diagrams are not a Bunny Lab requirement. Choose plain text or Mermaid according to the information being represented.
## Inline Formatting
### Inline Code
Use backticks for literal technical values:
- Commands and subcommands
- Filenames and paths
- Hostnames and FQDNs
- Dataset, pool, volume group, and storage identifiers
- Service names and package names
- Configuration keys and values
- Ports, IP addresses, and version strings
- UI values the operator must enter exactly
Examples:
- `CLUSTER-STORAGE/iscsi-proxmox`
- `/etc/pve/storage.cfg`
- `vg_proxmox_iscsi`
- `systemctl restart nginx`
- `America/Denver`
Do not wrap an entire sentence in inline code.
### Bold Text
Use bold for:
- GUI labels and navigation paths
- Critical words inside a warning
- A small amount of emphasis needed to prevent an operator mistake
Do not bold every product name, command, and noun.
### Italics
Use italics for a short aside, clarification, or definition. Do not rely on italics for safety-critical emphasis.
### Safety Emphasis
Use `Do not`, `must not`, and `cannot` for normal safety boundaries. Reserve `Do **NOT**` for a genuinely high-risk prohibition where missing the word could cause data loss, service interruption, or an unrecoverable configuration error.
Do not write entire warning paragraphs in bold or uppercase. The admonition type, specific title, and one emphasized boundary are sufficient.
### Quotation Marks and Source Punctuation
Use straight quotation marks in Markdown source. Place exact GUI paths and GUI labels inside the established bold quotation form, such as `"**Datacenter > Storage > Add > LVM**"`.
Use a colon to introduce a list, table, code block, or expected-output block when a complete introductory sentence precedes it. Do not add a colon to a heading solely because content follows it.
### Blockquotes
Use blockquotes for actual quotations, a short governing principle, or an intentional landing-page statement.
```markdown
> Assume technical literacy, but never assume local knowledge.
```
Do not use a blockquote as a substitute for an admonition. Operational notes, warnings, success states, and examples use the appropriate admonition type.
### Keyboard Keys
Use the keyboard-key syntax for an actual keypress when it improves an interactive command sequence:
```markdown
Press ++enter++ to accept the default sector value.
```
Use exact key names and keep this pattern sparse.
### Raw HTML
Do not use raw HTML for ordinary layout or styling. Use Markdown structures and supported extensions.
An inline HTML break MAY appear inside a Mermaid node label when required by the diagram syntax.
## Links and Cross-References
### Internal Links
Use descriptive Markdown links to connect related deployments, workflows, scripts, and references.
```markdown
Deploy a [Rancher RKE2 Cluster](<../../platforms/containerization/kubernetes/deployment/Rancher RKE2.md>) before continuing.
```
Internal links SHOULD:
- Use a source-relative path from the current Markdown file
- Include the `.md` source filename
- Match the actual target path and filename case
- Wrap a relative destination in `<...>` when the source path contains spaces
- Use an anchor only when linking to a specific stable heading
- Use descriptive link text rather than `click here`
- Be updated when either page moves or a linked heading changes
Do not use the public `https://kb.bunny-lab.io/...` URL for a link to another page in the same repository.
### External Links
Use HTTPS when the source supports it. Prefer descriptive text:
```markdown
[Reference Documentation](https://example.com/official-documentation)
```
A vendor reference link MAY appear immediately after Purpose when it is central to the deployment.
Avoid bare URL dumps. A raw URL is acceptable only in a temporary scratch section or when the literal URL itself is the configuration value being documented.
### Link Buttons and Icons
Button and icon syntax MAY be used for a high-value action link, such as opening an inventory editor or downloading an artifact. Do not use buttons and icons as the default link style.
### Anchors
Link to a heading anchor only after confirming the generated anchor. Keep linked heading text stable or update inbound links when the heading changes.
## Footnotes, Abbreviations, and Tooltips
Footnotes, abbreviation definitions, and tooltip-only explanations are supported Markdown features but are not routine Bunny Lab patterns.
They MAY be used in a blog or reference page for a citation, source note, or genuinely secondary explanation that would interrupt the main paragraph. Do not place a prerequisite, command, warning, replacement value, expected result, or recovery instruction in a footnote or tooltip.
Operational information belongs in normal prose, a list, a table, or an admonition where the operator will see it while following the page.
## Images and Screenshots
Screenshots are not the primary instructional vehicle.
Use an image only when:
- The spatial relationship of controls cannot be described clearly in text
- A hardware layout, wiring arrangement, or visual state is itself the subject
- The screenshot proves a state that commands or text output cannot represent
Every image MUST use a relative path and meaningful alt text.
Do not use a screenshot as a substitute for exact navigation paths, field values, commands, or validation criteria.
## Assumptions, Prerequisites, and Scope
Place assumptions immediately after Purpose unless architecture context must come first.
Use a section for several structured assumptions:
```markdown
## Assumptions
- TrueNAS Core is already installed
- The target ZFS pool exists and is healthy
- Every ProxmoxVE node can reach the iSCSI network
- The operator has `root` access on all affected systems
```
Use an admonition when the assumptions are compact or need emphasis:
```markdown
!!! info "Assumptions"
- The GuestVM uses an XFS filesystem.
- The virtual disk has already been expanded in the hypervisor.
- A current backup or snapshot exists.
```
Assumptions MUST identify hidden local dependencies, versions, privileges, topology, and starting state. Do not use assumptions to avoid documenting a prerequisite that the operator must actually perform.
## Validation
Validation is mandatory when a procedure changes storage, networking, authentication, virtualization, backups, certificates, data integrity, or another state where an unnoticed failure can cause later damage.
Validation MAY be:
- A `## Validation` section at the end
- A `### Validate ...` subsection immediately after a major phase
- An expected-output block
- A `!!! success` milestone after an explicit check
- A table of required states
Every validation item SHOULD identify both the check and the expected result.
Weak:
```markdown
- Verify that it works
```
Strong:
```markdown
- Run `lsblk /dev/sdX` on every ProxmoxVE node and confirm the new device size is reported.
- Run `vgs vg_proxmox_iscsi` and confirm the expected free capacity is available.
- Create, revert, and delete a test snapshot before placing production workloads on the storage.
```
Do not claim that a deployment is complete or production-ready until the documented validation proves the required state.
## Safety and Destructive Operations
Safety boundaries must be explicit and positioned before the affected action.
For destructive or high-risk work, document:
- What can be lost or interrupted
- What backup, snapshot, replica, or recovery path must exist
- Which system or node is authoritative
- Whether the command runs on one node, every node, or a specific role
- The exact point of no return
- The stop conditions that prohibit continuing
- The validation required before cleanup
Use `warning` for disruption or serious misconfiguration risk. Use `danger` for deletion, data loss, irreversible conversion, or destructive replacement.
When a document contains both an audit and cleanup phase, state clearly that the audit is read-only and the cleanup is destructive.
## Troubleshooting
Troubleshooting content SHOULD be symptom-led and operational.
Use one of these structures:
```markdown
## Troubleshooting
### Service Does Not Start
Describe the symptom, diagnostic command, likely cause, and resolution.
### Target Is Visible but Exposes No LUNs
Describe the symptom, diagnostic command, likely cause, and resolution.
```
Or, for a single incident pattern:
````markdown
## Symptoms
- The iSCSI session reconnects manually but is missing after reboot.
## Cause
The node record is configured for manual startup.
## Resolution
```sh
iscsiadm -m node --op update -n node.startup -v automatic
```
````
Include exact error text in inline code or a `text` block when it materially improves searchability.
Use `bug` for a known product defect or inconsistent behavior. Use `failure` for a confirmed failed state and its meaning.
Do not add a generic troubleshooting section containing only `check the logs`.
## Rollback, Recovery, and Cleanup
Add rollback or recovery instructions when a procedure can leave the environment degraded, partially migrated, or unable to start.
Rollback content SHOULD identify:
- What can be reversed
- What cannot be reversed
- Which backup, snapshot, configuration copy, or replica is used
- Whether services must be stopped first
- How to verify the rollback
Cleanup instructions MUST occur only after validation proves the replacement or migration is healthy.
Do not delete the old copy, source VM, previous configuration, or fallback path in the same phase that creates the replacement unless the procedure is explicitly designed and validated as an atomic replacement.
## Environment-Specific Values and Secrets
Bunny Lab documentation is allowed to be environment-specific. Known hostnames, internal IP addresses, storage IDs, paths, node names, domains, and service relationships SHOULD remain explicit when they are part of the actual lab implementation.
Do not generalize concrete environment details into vague placeholders merely to make the page look universally applicable. Use placeholders only for values the operator must choose or where publishing the actual value would be unsafe.
Secrets MUST be replaced with `REDACTED`, a clear placeholder, or a command that generates the value.
Good:
```ini title=".env"
DB_PASSWORD=REDACTED
ADMIN_TOKEN=REDACTED
TIMEZONE=America/Denver
```
Better when generation is relevant:
```sh
openssl rand -base64 32
```
Never fabricate an environment-specific value. When the source does not establish the value, use an explicit placeholder and explain how the operator obtains it.
## Reference Documentation
Link to authoritative vendor or project documentation when it helps the operator validate version-specific behavior, obtain downloads, or understand settings not reproduced locally.
The Bunny Lab page remains responsible for the local implementation. Do not replace local instructions with a sentence telling the operator to read the vendor documentation.
Use a concise link label such as:
```markdown
[Reference Documentation](https://example.com/documentation)
```
A longer page MAY use `## Reference Documentation` at the end with a short list of high-value sources.
## Converting Raw Notes Into Bunny Lab Documentation
Raw notes are evidence, not document structure. Notes may be chronological, repetitive, abbreviated, partially tested, copied from terminals, or mixed with personal observations. An agent MUST reorganize them into dependency order without erasing confirmed local facts or inventing missing ones.
### Establish the Document Contract
Before drafting, determine:
- The single primary intent of the page
- The correct repository category: deployment, workflow, script, reference, index, or blog
- The operator's starting state
- The system, node, account, shell, or WebUI used for each action
- The intended success state
- The destructive actions, stop conditions, and recovery path
- Whether the notes describe one page or several independent pages
Do not preserve the order in which notes were captured when that order is not the order in which the operator must act.
### Extract Facts Before Rewriting
Build an internal fact inventory from the supplied notes and repository context. Separate these categories before composing prose:
- Confirmed environment values
- Exact commands and configuration
- Execution locations and privilege requirements
- Dependencies and assumptions
- Observed output and success conditions
- Errors, symptoms, and resolutions
- Warnings and irreversible decisions
- First-person lab observations or preferences
- External references
- Unknown, contradictory, or unverified information
Repository context may resolve names, paths, or established relationships, but it must not be used to fabricate a fact that is absent or uncertain.
### Map Note Types to Markdown Structures
| **Raw Note Content** | **Bunny Lab Destination** |
| :--- | :--- |
| Goal, reason, or desired outcome | `## Purpose` |
| Existing state, dependency, privilege, version, or topology | `## Assumptions` or a titled `info` admonition |
| Architecture, ownership, or service relationship | Prose, table, plain-text diagram, or Mermaid diagram |
| Commands that accomplish one objective on one system | One coherent language-tagged code block |
| Complete file contents | Titled code block or peer-file content tab |
| Value the operator must enter exactly | Inline code or a field/value table |
| GUI navigation | Bold quoted path and nested bullets |
| Dangerous action or stop condition | Specific `warning` or `danger` admonition placed before the action |
| Verified result or milestone | Validation command, expected-output block, or `success` admonition |
| Error text and repair notes | Symptom-led troubleshooting section |
| Personal test result or implementation choice | Limited first-person lab context |
| Alternative methods or platforms | Content tabs when the alternatives are peers |
| Source URL | Descriptive Markdown link |
Do not convert every sentence into a bullet, every aside into an admonition, or every command into its own section. Select the structure that communicates the operational relationship.
### Reorder Into Operator Execution Flow
Arrange the extracted material in the order an operator needs it:
- Purpose
- Assumptions, scope, version context, and risk boundaries
- Architecture, variables, or dependencies
- Preparation
- State-changing actions
- Validation gates
- Troubleshooting
- Rollback, recovery, or cleanup
- Reference material
Move an explanation next to the command or decision it governs. Move a warning before the point of risk. Move cleanup after proof that the replacement state is healthy.
### Convert Shorthand Into Bunny Lab Prose
Expand shorthand only enough to make the action unambiguous. Preserve the technical meaning, environment names, and practical voice of the notes.
Raw note:
```text
pve nodes rescan first, pvresize ONE NODE, then vgscan others. do not run resize everywhere
```
Bunny Lab form:
````markdown
Run the block-device rescan on every ProxmoxVE node before resizing the physical volume.
!!! warning "Run `pvresize` on One Node Only"
Execute `pvresize` on exactly one ProxmoxVE node. Running it independently on multiple nodes can place shared LVM metadata at risk.
```sh
# Every ProxmoxVE Node
echo 1 > /sys/class/block/sdX/device/rescan
lsblk /dev/sdX
# One ProxmoxVE Node Only
pvresize /dev/sdX
# Remaining ProxmoxVE Nodes
pvscan
vgscan
```
````
Do not retain chat artifacts, brainstorming language, timestamps, speaker labels, or phrases such as `the user said` in the finished document.
### Preserve Exact Technical Material
Commands, configuration keys, paths, hostnames, IP addresses, filenames, service names, and error strings are literals. Preserve them exactly unless the task explicitly requires correction.
When notes contain an obviously malformed command or configuration value, do not silently repair it while presenting the result as confirmed. Correct it only when the correction can be validated from authoritative context, and explain a material behavior change when necessary.
### Handle Missing Information
Never guess a hostname, IP address, port, credential, path, version, command result, or product behavior.
When an interactive authoring workflow permits questions, request only the unresolved facts that materially affect correctness. When a document must be produced from incomplete notes without further input:
- Use a descriptive uppercase placeholder such as `<TARGET_SERVER>` or `<REQUIRES_CONFIRMATION>`
- Place a specific `warning` admonition immediately before any action that depends on the unknown value
- Add `## Outstanding Questions` only when unresolved items prevent the page from being safely complete
- Distinguish an unknown value from a redacted secret; use `REDACTED` only for sensitive data
- Do not fabricate expected output or claim a procedure was tested
A finalized page SHOULD contain no unresolved placeholders. A template is the deliberate exception.
### Handle Conflicting Notes
When two notes conflict, prefer the most recent explicit correction only when chronology and intent are clear. Otherwise, preserve both claims internally, identify the conflict, and avoid selecting one silently.
A conflicting command, target node, port, path, or destructive-action boundary is a correctness issue, not an editorial choice.
### Preserve Useful Personality
Retain first-person statements when they record a real lab choice, observed behavior, preference, or lesson learned. Remove hesitation, repetition, and conversational filler that do not change the technical meaning.
Do not make operational documentation sterile, but do not turn it into a transcript. The result should sound like Nicole explaining a procedure after organizing and validating her own notes.
## Factual Integrity and Verification
### Confirmed, Inferred, and Unverified Information
An agent MUST keep these states distinct:
- **Confirmed** — stated in the notes, visible in repository context, or validated by an authoritative source
- **Inferred** — logically derived from confirmed information but not directly stated
- **Unverified** — plausible but unsupported, version-sensitive, contradictory, or incomplete
Write confirmed facts directly. Label a material inference as an inference. Do not publish unverified information as a command, success condition, requirement, or environmental fact.
### Local Behavior Versus Product Behavior
Separate Nicole's observed lab behavior from a universal product claim.
Use first person for a local observation:
```markdown
In my lab environment, the partition table did not refresh until the server was rebooted.
```
Use neutral prose for verified product behavior:
```markdown
The service reads the updated configuration when it is restarted.
```
Do not generalize one lab result into a universal guarantee.
### Version Context
Document a version only when it affects commands, menus, syntax, behavior, compatibility, or expected output. Place compact version context in an `info` or `note` admonition near Purpose or Assumptions.
Do not add a version number merely to make a page appear precise. Never invent a tested version.
### Testing Claims
Use `tested`, `validated`, `working`, `production-ready`, or equivalent language only when the supplied evidence supports the claim. A command that appears syntactically valid is not proof that the workflow was executed successfully.
When validation has not been performed, describe the validation the operator must run rather than claiming the result.
## Agent Output Contract
When an agent is asked to create or revise a Bunny Lab page, the primary output is the complete Markdown document or an intentional patch to that document.
The agent MUST:
- Return valid Markdown source without CSS, theme, or presentation-layer changes
- Use the requested filename and repository location when provided
- Include complete front matter for a new ordinary page
- Begin ordinary pages with `## Purpose`
- Remove drafting commentary, chat references, and explanations about how the agent generated the page
- Preserve secrets as `REDACTED` or safe placeholders
- Avoid leaving template sections that do not apply
- Avoid adding unsupported content merely to make the document longer
- Keep unrelated files and unrelated sections unchanged during a targeted edit
When displaying a complete page inside another Markdown document or chat response, use an outer fence long enough to contain every inner fence safely. When writing directly to a repository file, do not wrap the entire document in an extra code fence.
This document is the style authority. Nearby pages are useful for environment facts and subject-specific context, but legacy formatting in those pages does not override this standard.
## Editing Existing Documentation
The repository contains historical variations. Future agents must distinguish a targeted edit from a deliberate normalization project.
### Targeted Edits
When the task changes one command, paragraph, link, warning, or section:
- Preserve the surrounding document structure and voice
- Match the local heading depth
- Normalize a Purpose opening that is within the requested edit scope to `## Purpose`
- Avoid rewrapping paragraphs
- Avoid changing unrelated bullet markers, headings, fences, or capitalization
- Do not reorder unrelated sections
- Do not rewrite the entire page to satisfy the newest template
- Correct malformed Markdown only when it is touched by or blocks the requested change
A small technical fix must not create a large formatting diff.
### Substantial Rewrites
When the task creates a new page or substantially rewrites an existing page:
- Apply this standard in full
- Add or correct front matter
- Normalize the opening to `## Purpose`
- Normalize heading hierarchy
- Use accurate fence identifiers
- Remove accidental trailing whitespace
- Replace malformed admonitions
- Add missing assumptions, context, safety boundaries, and validation
- Preserve environment-specific facts and useful first-person observations
- Update internal links affected by the rewrite
### Legacy Patterns
The following patterns may exist in older pages but SHOULD NOT be copied into new content:
- Ordinary pages beginning with a duplicated H1
- Pages beginning at H3 without an H2 parent
- `## Purpose:` with a trailing colon
- A bold Purpose label in any form, including `**Purpose**:` and `**Purpose:**`
- A space in fence declarations such as ````` sh`````
- `jsx` used for `.env`, paths, registry values, or plain text
- Asterisks used as the default bullet marker
- Unquoted admonition titles
- Uppercase or custom admonition types
- Empty `.env` blocks containing `Not Applicable`
- Horizontal rules between every section
- Raw URLs used as the normal link style
- Hard-wrapped prose or trailing-space line breaks
Do not copy a legacy pattern into new material. During a narrow edit, avoid expanding the task into a whole-file style migration unless the legacy construct is touched by the change, breaks rendering, creates risk, or the user explicitly requests normalization.
## Agent Authoring Workflow
### Before Writing
An agent MUST:
- Identify the page's primary content type
- Read the full target page when editing an existing file
- Inspect nearby pages when environment facts or subject-specific context are unclear; do not let legacy formatting override this standard
- Extract the actual environment names, paths, ports, hosts, roles, and assumptions from available source material
- Determine the execution context of every command
- Identify destructive actions, one-node-only actions, reboots, logouts, and state transitions
- Confirm how much structure the page requires without changing the mandatory `## Purpose` opening
### While Writing
An agent MUST:
- Use the Bunny Lab voice rather than generic documentation filler
- Keep each prose paragraph on one source line
- Use two spaces between sentences in the same paragraph
- Maintain one blank line between Markdown blocks
- Use action-oriented headings
- Group commands by objective and execution context
- Put warnings before risky actions
- Put validation before the next dependent phase
- Use exact GUI labels and exact literal values
- Use placeholders only when the value is unknown or sensitive
- Avoid inventing commands, output, URLs, environment values, or product behavior
### Before Returning the Document
An agent MUST verify:
- Front matter opens and closes correctly
- Tags are relevant and consistently capitalized
- The page-title rule is correct for the document type
- Heading levels do not skip unexpectedly
- Admonition titles are quoted and bodies are indented four spaces
- Content tabs and nested blocks are indented correctly
- Every code fence closes and has the correct language identifier
- No non-JSX block is fenced as `jsx`
- Commands and output are separated
- Annotation markers and explanations match
- Internal links point to real source files and anchors
- No secret or credential is exposed
- No paragraph was hard-wrapped
- No trailing whitespace remains
- The file ends with a newline
- The document can be followed top to bottom without hidden prerequisites
- High-risk actions have explicit validation and recovery context
When a repository-provided Markdown validation command is available, run it. Fix the Markdown source error rather than masking it in an unrelated file.
## Canonical Templates
The templates in this section are authoritative starting points. Remove sections that do not apply rather than leaving placeholder headings in a completed document.
### Full Deployment Template
````markdown
---
tags:
- <PRIMARY_PRODUCT>
- <SECONDARY_TECHNOLOGY>
- <DOMAIN>
---
## Purpose
This document describes how to deploy <SYSTEM_OR_SERVICE> in the Bunny Lab environment. It covers <PRIMARY_SCOPE> and validates <SUCCESS_STATE> before the deployment is considered complete.
!!! info "Assumptions"
- <OPERATING_SYSTEM_OR_PLATFORM_ASSUMPTION>
- <PRIVILEGE_ASSUMPTION>
- <NETWORK_OR_STORAGE_ASSUMPTION>
- <DEPENDENCY_ASSUMPTION>
## Architecture
```mermaid
sequenceDiagram
actor Operator
participant Service
participant Dependency
Operator->>Service: Deploy and configure
Service->>Dependency: Establish integration
Dependency-->>Service: Return successful response
```
## Prepare the Server
Run the following on `<TARGET_SERVER>`:
```sh
# Install Required Packages
<COMMANDS>
# Create Required Directories
<COMMANDS>
```
## Configure the Service
```yaml title="/path/to/config.yml"
<CONFIGURATION>
```
## Start the Service
```sh
<COMMANDS>
```
## Validation
- Run `<VALIDATION_COMMAND>` and confirm `<EXPECTED_RESULT>`.
- Access `<SERVICE_URL>` and confirm `<EXPECTED_STATE>`.
- Verify `<DEPENDENCY_OR_INTEGRATION>` before placing the service into normal use.
## Troubleshooting
### <FAILURE_SYMPTOM>
Describe the observable symptom, diagnostic command, likely cause, and resolution.
## Rollback
Describe how to restore the previous configuration or remove the failed deployment safely.
````
### Containerized Service Deployment Template
````markdown
---
tags:
- <SERVICE>
- <FUNCTION>
- Docker
---
## Purpose
<ONE_OR_TWO_SENTENCES_EXPLAINING_WHAT_THE_SERVICE_DOES_AND_WHY_IT_EXISTS>.
[Reference Documentation](<OFFICIAL_DOCUMENTATION_URL>)
!!! info "Assumptions"
- Docker and Docker Compose are already installed.
- The `docker_network` network already exists.
- Persistent data is stored beneath `/srv/containers/<SERVICE>`.
## Docker Configuration
```yaml title="docker-compose.yml"
services:
<SERVICE>:
image: <IMAGE>
container_name: <SERVICE>
restart: unless-stopped
environment:
- TZ=${TIMEZONE}
volumes:
- /srv/containers/<SERVICE>:/config
networks:
docker_network:
ipv4_address: <CONTAINER_IP>
networks:
docker_network:
external: true
```
```ini title=".env"
TIMEZONE=America/Denver
<SECRET_NAME>=REDACTED
```
## Traefik Reverse Proxy Configuration
Include this section only when the service is exposed through Traefik.
```yaml title="<FQDN>.yml"
http:
routers:
<SERVICE>:
entryPoints:
- websecure
tls:
certResolver: letsencrypt
service: <SERVICE>
rule: Host(`<FQDN>`)
services:
<SERVICE>:
loadBalancer:
servers:
- url: http://<CONTAINER_IP>:<PORT>
passHostHeader: true
```
## Validation
- Run `docker compose ps` and confirm every required container is healthy or running.
- Access `https://<FQDN>` and complete the initial onboarding process.
- Confirm persistent data exists beneath `/srv/containers/<SERVICE>`.
````
### Workflow Template
````markdown
---
tags:
- <PRIMARY_PRODUCT>
- <OPERATION>
- <DOMAIN>
---
## Purpose
This workflow describes how to <OPERATION>. It begins from <STARTING_STATE> and is complete when <SUCCESS_STATE>.
!!! info "Assumptions"
- <STARTING_STATE_ASSUMPTION>
- <PRIVILEGE_ASSUMPTION>
- <BACKUP_OR_SNAPSHOT_ASSUMPTION>
!!! warning "<SPECIFIC_RISK_TITLE>"
Describe the service interruption, destructive action, or condition that requires the operator to stop.
## Prepare the Environment
Describe or run the preparation required before the state-changing operation.
```sh
<COMMANDS>
```
## Perform the Operation
State exactly where the commands run and whether the action applies to one node or every node.
```sh
<COMMANDS>
```
## Validate the Result
```sh
<VALIDATION_COMMANDS>
```
Expected result:
```text
<EXPECTED_OUTPUT_OR_STATE>
```
## Rollback
Describe the recovery path and the condition that requires it.
## Troubleshooting
### <SYMPTOM>
Describe the diagnostic check, likely cause, and resolution.
````
### GUI or WebUI Workflow Template
````markdown
---
tags:
- <PRODUCT>
- <OPERATION>
- <DOMAIN>
---
## Purpose
This workflow describes how to <OPERATION> through the <PRODUCT> WebUI. It is complete when <SUCCESS_STATE>.
!!! info "Assumptions"
- <ACCESS_OR_ROLE_ASSUMPTION>
- <STARTING_STATE_ASSUMPTION>
- <BACKUP_OR_RECOVERY_ASSUMPTION>
## Configure <OBJECT_OR_FEATURE>
- Navigate to "**<TOP_LEVEL_MENU> > <SUBMENU> > <ACTION>**"
- Select "**<EXACT_OPTION>**"
- Enter the required values:
| **Field** | **Value** | **Notes** |
| :--- | :--- | :--- |
| <FIELD> | `<VALUE>` | <CONTEXT> |
!!! warning "<SPECIFIC_RISK_TITLE>"
Describe the setting, commitment action, or service impact the operator must understand before continuing.
- Click "**<COMMIT_ACTION>**"
## Validation
- Navigate to "**<STATUS_OR_RESULT_PATH>**" and confirm `<EXPECTED_STATE>`.
- Run `<OPTIONAL_CLI_VALIDATION>` and confirm `<EXPECTED_RESULT>`.
## Rollback
Describe the exact WebUI path or recovery action used to restore the prior state.
````
### Troubleshooting Runbook Template
````markdown
---
tags:
- <PRODUCT>
- Troubleshooting
- <DOMAIN>
---
## Purpose
This runbook resolves <FAILURE_CONDITION>. It applies when <SCOPE_AND_STARTING_STATE>.
## Symptoms
- <OBSERVABLE_SYMPTOM>
- `<EXACT_ERROR_TEXT>`
- <FAILED_VALIDATION_OR_SERVICE_STATE>
## Cause
Describe the confirmed or most likely cause. Separate verified facts from assumptions.
!!! warning "Stop Condition"
Do not continue when <UNSAFE_CONDITION>.
## Diagnostics
```sh
<READ_ONLY_DIAGNOSTIC_COMMANDS>
```
## Resolution
```sh
<STATE_CHANGING_COMMANDS>
```
## Validation
- Run `<COMMAND>` and confirm `<EXPECTED_RESULT>`.
- Confirm the original symptom no longer occurs.
## Rollback
Describe how to undo the resolution if the service enters a worse state.
````
### Script Template
````markdown
---
tags:
- <PRIMARY_TECHNOLOGY>
- <LANGUAGE>
- Scripting
---
## Purpose
This script <PRIMARY_FUNCTION>.
!!! info "Requirements"
- Run from <REQUIRED_CONTEXT>.
- Install or import `<DEPENDENCY>`.
- Replace `<PLACEHOLDER>` before execution.
## Script
```powershell title="<SCRIPT_NAME>.ps1"
<SCRIPT_CONTENT>
```
## Usage
```powershell
.\<SCRIPT_NAME>.ps1 -<PARAMETER> <VALUE>
```
## Output
The script writes `<OUTPUT_FILE>` and reports `<SUCCESS_OR_FAILURE_STATE>`.
## Notes
- <EDGE_CASE_OR_LIMITATION>
- <DESTRUCTIVE_OR_PERFORMANCE_CONSIDERATION>
````
### Minimal Command or One-Liner Template
````markdown
---
tags:
- <PRIMARY_TECHNOLOGY>
- <OPERATION>
- <DOMAIN>
---
## Purpose
This command <PRIMARY_FUNCTION>.
```sh
<COMMAND>
```
## Notes
- Run the command on `<EXECUTION_CONTEXT>`.
- The command creates or changes `<SIDE_EFFECT>`.
````
Omit `## Notes` when the execution context and side effects are already obvious from the Purpose sentence and command. Do not replace `## Purpose` with a bold label merely because the page is short.
### Reference and Inventory Template
````markdown
---
tags:
- <PRIMARY_SYSTEM>
- <REFERENCE_TOPIC>
- <DOMAIN>
---
## Purpose
This document records <REFERENCE_SCOPE>. Update it whenever <MAINTENANCE_TRIGGER>.
## Scope
- <IN_SCOPE_ITEM>
- <IN_SCOPE_ITEM>
- <OUT_OF_SCOPE_BOUNDARY>
## <REFERENCE_TOPIC>
| **Field** | **Value** | **Notes** |
| :--- | :--- | :--- |
| <FIELD> | `<VALUE>` | <CONTEXT> |
## Maintenance Notes
- Update this page after <CHANGE_EVENT>.
- Validate the reference against `<AUTHORITATIVE_SOURCE>`.
````
### Index Page Template
````markdown
---
tags:
- <CATEGORY>
- Index
- Documentation
---
# <Category>
## Purpose
<ONE_SENTENCE_DESCRIBING_THE_FOLDER_AND_ITS_PRIMARY_INTENT>.
## Includes
- <CONTENT_CLASS>
- <CONTENT_CLASS>
- <CONTENT_CLASS>
````
### Root Landing Page Template
The root `index.md` is a deliberate exception to ordinary front matter and Purpose requirements.
````markdown
# Home
## Homelab Documentation Structure
Describe what the knowledgebase contains, the environment it represents, and the expectations that apply to readers.
## Top-Level Sections
**Deployments**
- Platform, service, and automation deployment guides
**Workflows**
- Day-2 runbooks, maintenance procedures, and troubleshooting flows
**Scripts**
- Quick-use Bash, PowerShell, and Batch scripts
**Reference**
- Foundations, infrastructure inventory, and stable technical reference material
**Blog**
- Narrative posts, experiments, and lessons learned
## Disclaimers and Scope
!!! warning "Homelab-Specific Guidance"
Explain that the documentation reflects Nicole's environment, goals, and risk tolerance.
````
### Blog Post Template
````markdown
---
draft: false
date: <YYYY-MM-DD>
updated: <YYYY-MM-DD>
authors:
- nicole
categories:
- General
tags:
- Blog
- <PRIMARY_TOPIC>
- <SECONDARY_TOPIC>
---
# <Post Title>
Open with the personal or technical context that made the subject worth documenting. Establish what you expected, what happened, or what question you were trying to answer.
## <First Major Topic>
Explain the relevant experience, technical detail, or decision.
## <What Changed or What You Tried>
Describe the actions, observations, and results.
## Lessons Learned
Summarize what worked, what failed, and what you would do differently.
````
## Anti-Patterns
Do not introduce the following patterns into new documentation:
- Generic AI-generated introductions or conclusions
- A duplicated H1 on an ordinary operational page
- A bold Purpose label instead of `## Purpose`
- More than one H1
- Heading levels chosen for visual size rather than document hierarchy
- H3 headings without an H2 parent
- Manually numbered routine procedures
- `Step 1`, `Step 2`, and `Step 3` headings when action headings are sufficient
- A horizontal rule after every section
- Paragraphs hard-wrapped across several source lines
- Single-space sentence separation inside a paragraph
- Trailing whitespace used for line breaks
- Asterisks as the default bullet marker
- Two-space nested indentation or tab indentation
- Untitled or malformed front matter
- Navigation ordering metadata added to ordinary pages
- Unquoted custom admonition titles
- Warnings placed after the risky command
- Admonitions used as decorative colored boxes
- Tabs used for sequential phases
- A one-tab tab set
- A space between backticks and the fence language
- Missing or inaccurate fence language identifiers
- `jsx` used for non-JSX content
- Commands mixed with output without an explicit transcript format
- Shell prompts in copy/paste command blocks
- One command per code block when the commands form one coherent operation
- Several unrelated systems combined in one unlabeled code block
- Empty `.env` examples containing `Not Applicable`
- GUI instructions without exact navigation paths or field values
- Screenshots used instead of reproducible text instructions
- Vague statements such as `configure this as needed`
- Hidden prerequisites or unexplained privilege requirements
- Decorative emoji in ordinary operational headings
- Unresolved placeholders presented as finished environment values
- Claims that a procedure was tested without supporting evidence
- Destructive cleanup before validation
- Raw internal site URLs instead of source-relative links
- Broken relative links or stale heading anchors
- Real secrets, tokens, passwords, or private keys
- Fabricated environment values, commands, output, or product behavior
- Mass reformatting unrelated to the requested change
## Final Agent Checklist
A document is complete only when all applicable statements are true:
- The page has one clear primary intent.
- Front matter is valid and tags are meaningful.
- The title and H1 behavior match the document type.
- Every ordinary page begins with the exact heading `## Purpose`.
- Purpose clearly states what the page accomplishes and where it applies.
- Assumptions and privileges are explicit.
- Major actions use `##` headings and sub-actions use `###` headings.
- Headings are concise, action-oriented where appropriate, and correctly nested.
- Every paragraph remains on one source line.
- Sentences on the same line use two-space separation.
- Markdown blocks use consistent one-blank-line spacing.
- Lists use hyphens and four-space nesting.
- GUI paths use exact bold quoted labels separated by `>`.
- Code fences have no space before the correct language identifier.
- File-content blocks use meaningful titles.
- Commands are grouped by objective and execution context.
- Commands contain no shell prompts.
- Output is separated into `text` blocks or example admonitions.
- Annotation numbers match their code markers.
- Warnings appear before risk and success callouts follow validation.
- Tabs contain alternatives or peer configuration artifacts rather than sequential work.
- Tables are used only for genuinely tabular information.
- Diagrams explain a real relationship or sequence.
- Internal links resolve to existing Markdown files and stable anchors.
- Environment-specific details are preserved when known.
- No template token, `<REQUIRES_CONFIRMATION>`, or `PLACEHOLDER` remains unless it is an intentional operator-replacement value.
- Secrets are redacted or generated safely.
- Risky procedures include stop conditions, validation, and recovery context.
- No unsupported testing claim, expected output, command, or environment value was invented.
- No drafting commentary or AI-generation language remains in the page.
- No unrelated content was reformatted during a targeted edit.
- The file contains no trailing whitespace and ends with a newline.
## Summary
Bunny Lab documentation is deterministic, environment-aware, direct, and operational without being stripped of personality. It uses explicit commands, exact GUI paths, contextual explanations, visible safety boundaries, and testable validation while retaining Nicole's established second-person voice and practical first-person lab observations.
A document is incomplete when an operator cannot determine **where to act, what to run, what to expect, when to stop, and how to prove the result** from the Markdown alone.