Writing Guide
The Makechain documentation is the canonical reference for the protocol, its APIs, and tooling. This guide provides editorial standards for writing clear, consistent, and accurate documentation.
This page covers:
General Documentation
Voice and tone
Write in a technical, direct voice. Assume the reader is a developer who understands cryptography, distributed systems, and version control. Do not over-explain fundamentals — link to external references when background is needed.
Be precise, not verbose. Every sentence should convey information. Cut filler words, hedging phrases ("it should be noted that"), and unnecessary qualifiers.
- Correct: "Messages are ordered by Simplex BFT consensus with sub-second finality."
- Incorrect: "It's worth noting that messages are typically ordered by what we call Simplex BFT consensus, which generally provides sub-second finality."
Second person
Write in the second person. Use "you" when addressing the reader directly.
- Correct: "You submit messages via the gRPC
SubmitMessageendpoint." - Incorrect: "We submit messages via the gRPC
SubmitMessageendpoint."
Reserve "we" for statements where the Makechain team is the explicit subject: "We plan to add P-256/WebAuthn as a secondary signature scheme."
Present tense
Use present tense to describe how the system works. Use future tense only for features that do not exist yet.
- Correct: "The execution engine processes messages in two phases."
- Incorrect: "The execution engine will process messages in two phases."
Active voice
Use active voice. Passive voice obscures the subject and adds unnecessary words.
- Correct: "The leader proposes blocks by draining the mempool."
- Incorrect: "Blocks are proposed by the leader by draining the mempool."
Short sentences
One idea per sentence. If a sentence has more than one comma, split it. Follow a long sentence with a short one.
- Correct: "Each project group operates on its own copy-on-write overlay store. This ensures isolation between projects."
- Incorrect: "Each project group operates on its own copy-on-write overlay store that can read the base state plus any account changes from Phase 1 via the snapshot store, which ensures isolation between projects."
Gender-neutral language
Use "they" as a singular pronoun. Address groups as "developers," "users," or "validators."
No emojis
Do not use emojis in documentation. Color and visual interest come from the shape system, not emoji.
Spelling and Terminology
Makechain-specific terms
Use these terms consistently:
| Term | Usage | Not |
|---|---|---|
| Make ID | The account identifier. Abbreviate as mid in code contexts. | MakeID, make-id |
| message | Lowercase when referring to the concept. | Message (unless starting a sentence) |
| message type | Refer to specific types in SCREAMING_SNAKE_CASE with backticks: PROJECT_CREATE | ProjectCreate, project_create |
| project ID | Lowercase "ID." Always note it is content-addressed (BLAKE3 hash of the creation message). | Project Id, projectId |
| ref | A branch or tag pointer. Plural: "refs." | reference, branch (unless clarifying) |
| scope | Key permission level. Three scopes: OWNER, SIGNING, AGENT. Show in ALL CAPS without backticks when used as a label. | scope level, permission |
| DA layer | Data availability layer. Spell out on first use per page, then abbreviate. | data layer, blob store |
| state root | The BLAKE3 merkle root of all state. No hyphen. | stateroot, state-root |
| mempool | One word, lowercase. | mem-pool, memory pool |
| consensus | Lowercase unless starting a sentence. Refer to the specific algorithm as "Simplex BFT." | Consensus |
External product casing
Match the canonical casing of external tools and protocols:
- Ed25519 (not ed25519 or ED25519)
- BLAKE3 (not blake3 or Blake3)
- gRPC (not GRPC or Grpc)
- grpc-web (lowercase with hyphen)
- protobuf (lowercase)
- Rust (capitalized)
- rayon (lowercase — it's a crate name)
- Cloudflare (capitalized)
- Ethereum (capitalized), but
ETH_ADDRESSin code - Solana (capitalized), but
SOL_ADDRESSin code
Abbreviations
Spell out abbreviations on first use per page, followed by the abbreviation in parentheses:
- "data availability (DA) layer"
- "Byzantine Fault Tolerant (BFT) consensus"
- "compare-and-swap (CAS)"
These abbreviations are acceptable without expansion: HTTP, gRPC, URL, API, CLI, SDK, CI/CD, hex.
Do not use Latin abbreviations. Write "for example" instead of "e.g." and "that is" instead of "i.e."
Numbers and units
- Byte counts are explicit: "32 bytes," "64 bytes"
- Hash sizes: "BLAKE3 (32 bytes)" on first mention per page
- Time: use "ms" for milliseconds, "s" for seconds — "~200ms block time"
- Throughput: "10,000+ messages per second"
- Storage: use "GB" for gigabytes, "KB" for kilobytes
- Hex values: lowercase, no
0xprefix unless referencing a state key prefix — "prefix0x01"
Formatting
Headings
One H1 per page — the page title. No shape prefix on H1.
All H2 headings get a shape prefix using an inline <img>:
## <img src="/shape-square.svg" width="14"
style={{display: 'inline', verticalAlign: 'middle', marginRight: '8px'}}
/>Section TitleH3 headings are plain text — no shape, no decoration. Do not skip heading levels (H2 → H4).
Use sentence case for all headings:
- Correct:
## State root computation - Incorrect:
## State Root Computation
Exception: capitalize product names in headings — "Creating your first EAS build," "Configuring Simplex BFT."
Shape assignment
Cycle through the five brand shapes for H2s within a page:
square (
#00EEBE) — primary conceptcircle (
#7A3BF7) — secondary / supportingtriangle (
#FA7CFA) — technical detailstar (
#FAD030) — configuration / optionsheart (
#FE0302) — supplementary / coda
For pages with more than 5 sections, pull from the extended shape set: diamond, hexagon, bolt, shield, sparkle, leaf, flame.
Inline code
Use backticks for:
- Message types:
PROJECT_CREATE,COMMIT_BUNDLE - Field names:
project_id,old_hash,da_reference - Hex prefixes:
0x01,0x0A - CLI commands:
cargo test,bun run build - RPC methods:
SubmitMessage,GetProject - Rust types and crate names:
MemoryStore,commonware-consensus
Do not use backticks for:
- Product names: Makechain, Simplex BFT, Commonware
- Scope labels: OWNER, SIGNING, AGENT (use ALL CAPS plain text)
- File names and directories — use bold instead: app.json, src/state/
File and directory names
Use bold for file names, directory names, and file extensions in prose:
- Correct: "Your protocol buffer definition is in proto/makechain.proto."
- Incorrect: "Your protocol buffer definition is in
proto/makechain.proto."
Code blocks
Always specify the language for fenced code blocks:
```rust
let project_id = blake3::hash(&message_bytes);
```Use bash for shell commands, rust for Rust code, json for JSON, and plain triple backticks (no language) for ASCII diagrams and pseudocode.
Tables
Use markdown tables for structured reference data. Tables are the primary format for:
- Message type lists with descriptions and scopes
- Configuration parameters with defaults
- State key prefixes and namespaces
- Storage limits
- Error types with triggers
Always include a header row with separator:
| Type | Description | Scope |
|------|-------------|-------|
| `PROJECT_CREATE` | Create a new project | SIGNING |Lists
Use dashes (-) for unordered lists, not asterisks. Start numbered lists at 1.
Use bold for the lead term in definition-style lists:
- **Permissionless** — anyone can create projects and push code
- **Content-addressed** — project IDs are BLAKE3 hashes of creation messagesUse em dashes (—) to separate the term from its definition, not colons or hyphens.
Links
Link descriptive text, not "here" or "this page":
- Correct: "See the storage limits for per-account capacity."
- Incorrect: "See storage limits here."
Use relative paths for internal links: /protocol/overview, not https://makechain.pages.dev/protocol/overview.
ASCII diagrams
Use box-drawing characters for architecture diagrams in plain fenced code blocks:
┌─────────────┐
│ Component │
└──────┬──────┘
│
┌──────▼──────┐
│ Next Layer │
└─────────────┘Diagrams should be self-contained and readable without surrounding text.
Protocol Documentation
Protocol pages document the specification. They are reference material — precise, complete, and authoritative.
Describe behavior, not implementation
Protocol docs describe what the system does, not how the Rust code implements it. Reference implementation details (crate names, function names) belong in code comments and CLAUDE.md, not in user-facing docs.
- Correct: "Account-level messages are applied serially because they modify shared account state."
- Incorrect: "Account-level messages are applied serially using the
apply_account_messagesfunction inexecution.rs."
Document the envelope
When introducing a message type, always specify:
- The message type name in
SCREAMING_SNAKE_CASE - The required key scope (OWNER, SIGNING, or AGENT)
- The conflict key or ordering mechanism (CAS, LWW, append-only)
- The semantics category (1P or 2P)
Show the state change
For each message type, describe:
- Preconditions — what must be true for the message to be accepted
- Effect — what state changes when the message is applied
- Failure modes — what errors are returned and when
Use tables for message type reference
The canonical format for listing message types:
| Type | Description | Required Scope |
|------|-------------|---------------|
| `PROJECT_CREATE` | Create a new project with name and visibility | SIGNING |
| `PROJECT_REMOVE` | Remove a project (hides refs, commits, collaborators) | OWNER |Conflict resolution rules
Always state the conflict resolution rule explicitly:
- "On a timestamp tie, remove wins."
- "Last-write-wins per conflict key
(project_id, field)." - "Compare-and-swap: includes expected current hash. If the ref has moved, the update is rejected."
API Documentation
API pages document the gRPC service. They are functional reference — developers look things up here while coding.
RPC method format
Document each RPC with:
- Method name in backticks:
GetProject - Request fields as a table
- Response fields as a table
- A curl/grpcurl example when useful
- Error conditions
Field descriptions
Write useful descriptions. Teach the developer something beyond what the type signature shows:
- Correct: "
project_id— the BLAKE3 hash of the originalPROJECT_CREATEmessage (32 bytes, hex-encoded)" - Incorrect: "
project_id— the project ID"
Pagination
All list endpoints use cursor-based pagination. Document the pattern once and reference it:
cursor— opaque string from a previous response. Omit for the first page.limit— maximum items to return. Default 50, maximum 200.
Streaming endpoints
For streaming RPCs (SubscribeMessages, SubscribeBlocks), document:
- The filter parameters
- What triggers a message on the stream
- Whether the stream replays historical data or is live-only
Page Structure
Every documentation page follows this structure:
# Page Title ← H1, no shape
Introductory paragraph. ← 1-2 sentences establishing context
## <shape> First Section ← H2 with shape
Content...
### Subsection ← H3, plain
Content...
## <shape> Second Section ← H2 with shape
Content...Opening paragraph
Start every page with 1-2 sentences that tell the reader what this page covers and why it matters. No preamble, no "In this section we will discuss..."
- Correct: "Makechain enforces per-account storage limits to prevent unbounded state growth."
- Incorrect: "This page describes the storage limits system. Storage limits are an important part of the protocol."
One concept per page
Each page covers one topic. If you find yourself writing "see also" to another section on the same page, consider whether the content should be its own page.
End with edges
Close pages with edge cases, error types, or future considerations. The reader who reaches the bottom is looking for details.
Punctuation
Oxford commas
Use Oxford commas: "projects, commits, and refs" — not "projects, commits and refs."
Em dashes
Use em dashes (—) to set off parenthetical clauses. No spaces around em dashes:
- Correct: "Every operation is a cryptographically signed message — verifiable without external lookups."
- Incorrect: "Every operation is a cryptographically signed message - verifiable without external lookups."
In MDX, write — directly (Unicode em dash). The — entity also works.
Double quotes
Use double quotes in prose. Reserve single quotes for nested quotation or code contexts:
- Correct: Set the field named "id" to your project's ID.
- Incorrect: Set the field named 'id' to your project's ID.
Possessives
Singular possessive: add 's regardless of final consonant — "BLAKE3's digest," "the process's state."
Plural possessive ending in s: add just the apostrophe — "the validators' signatures."
Slashes
No spaces around slashes: "client/server," "Android/iOS."
Glossary
Core terms used throughout Makechain documentation.
Protocol
| Term | Definition |
|---|---|
| Message | A signed, self-authenticating operation envelope containing a BLAKE3 hash, Ed25519 signature, signer public key, and operation payload |
| Message type | The specific operation: PROJECT_CREATE, COMMIT_BUNDLE, REF_UPDATE, etc. |
| 1P (one-phase) | Unilateral state change with no paired undo message. Categories: Singleton, LWW Register, Append-only, State transition |
| 2P (two-phase) | Add/Remove pairs operating on a set. Remove wins on timestamp tie |
| CAS | Compare-and-swap — optimistic locking where an update includes the expected current value |
| LWW | Last-write-wins — the most recent message by consensus order overwrites prior state |
| Remove-wins | On a timestamp tie between add and remove, the remove takes precedence |
| Conflict key | The tuple that identifies which state slot a message targets, for example (project_id, field) |
Identity
| Term | Definition |
|---|---|
| Make ID (MID) | Unique account identifier (uint64) assigned by the onchain registry |
| Scope | Permission level for a registered key: OWNER (full control), SIGNING (push, manage), AGENT (automated actions) |
| Claim signature | Cryptographic proof linking an external address to a Make ID. Message format: makechain:verify:<mid> |
Consensus
| Term | Definition |
|---|---|
| Simplex BFT | Single-chain Byzantine Fault Tolerant consensus protocol from the Commonware library |
| Block | A batch of messages ordered by consensus. ~200ms block time |
| Finality | A block is final after two consecutive blocks are notarized (2-chain rule). ~300ms |
| Notarization | A 2/3+ validator vote to accept a proposed block |
| Mempool | Queue of validated messages waiting to be included in a block |
Execution
| Term | Definition |
|---|---|
| Account pre-pass | Phase 1: serial execution of account-level messages that modify shared state |
| Project execution | Phase 2: parallel execution of project-scoped messages grouped by project_id |
| Overlay store | Copy-on-write state store providing isolation between parallel project groups |
| Snapshot store | Read-only view of base state plus account pre-pass diffs, used as the base for overlay stores |
| State root | BLAKE3 merkle root combining all per-project roots in sorted order |
Storage
| Term | Definition |
|---|---|
| Storage unit | Yearly capacity allocation for an account. Default: 1 (free tier) |
| DA layer | Data availability layer — separate storage for file content (blobs, trees), referenced by da_reference in commit bundles |
| Pruning | Automatic removal of oldest unprotected commit metadata when a project exceeds its limit. Commits referenced by active refs are never pruned |
| Ref | A named pointer (branch or tag) to a commit hash |
| Fast-forward | A ref update where the new commit is a descendant of the current ref target |
Infrastructure
| Term | Definition |
|---|---|
| Commonware | The library of distributed systems primitives that Makechain builds on |
| tonic | Rust gRPC framework used for the API layer |
| rayon | Rust data-parallelism library used for parallel project execution |
| QMDB | Queryable Merkle Database — planned persistent state backend |