Are you an LLM? Read llms.txt for a summary of the docs, or llms-full.txt for the full context.
Writing Guide – Makechain
Skip to content

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 SubmitMessage endpoint."
  • Incorrect: "We submit messages via the gRPC SubmitMessage endpoint."

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:

TermUsageNot
Make IDThe account identifier. Abbreviate as mid in code contexts.MakeID, make-id
messageLowercase when referring to the concept.Message (unless starting a sentence)
message typeRefer to specific types in SCREAMING_SNAKE_CASE with backticks: PROJECT_CREATEProjectCreate, project_create
project IDLowercase "ID." Always note it is content-addressed (BLAKE3 hash of the creation message).Project Id, projectId
refA branch or tag pointer. Plural: "refs."reference, branch (unless clarifying)
scopeKey permission level. Three scopes: OWNER, SIGNING, AGENT. Show in ALL CAPS without backticks when used as a label.scope level, permission
DA layerData availability layer. Spell out on first use per page, then abbreviate.data layer, blob store
state rootThe BLAKE3 merkle root of all state. No hyphen.stateroot, state-root
mempoolOne word, lowercase.mem-pool, memory pool
consensusLowercase 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_ADDRESS in code
  • Solana (capitalized), but SOL_ADDRESS in 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 0x prefix unless referencing a state key prefix — "prefix 0x01"

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 Title

H3 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:

  1. square (#00EEBE) — primary concept
  2. circle (#7A3BF7) — secondary / supporting
  3. triangle (#FA7CFA) — technical detail
  4. star (#FAD030) — configuration / options
  5. heart (#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 messages

Use 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_messages function in execution.rs."

Document the envelope

When introducing a message type, always specify:

  1. The message type name in SCREAMING_SNAKE_CASE
  2. The required key scope (OWNER, SIGNING, or AGENT)
  3. The conflict key or ordering mechanism (CAS, LWW, append-only)
  4. 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:

  1. Method name in backticks: GetProject
  2. Request fields as a table
  3. Response fields as a table
  4. A curl/grpcurl example when useful
  5. 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 original PROJECT_CREATE message (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 &mdash; 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

TermDefinition
MessageA signed, self-authenticating operation envelope containing a BLAKE3 hash, Ed25519 signature, signer public key, and operation payload
Message typeThe 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
CASCompare-and-swap — optimistic locking where an update includes the expected current value
LWWLast-write-wins — the most recent message by consensus order overwrites prior state
Remove-winsOn a timestamp tie between add and remove, the remove takes precedence
Conflict keyThe tuple that identifies which state slot a message targets, for example (project_id, field)

Identity

TermDefinition
Make ID (MID)Unique account identifier (uint64) assigned by the onchain registry
ScopePermission level for a registered key: OWNER (full control), SIGNING (push, manage), AGENT (automated actions)
Claim signatureCryptographic proof linking an external address to a Make ID. Message format: makechain:verify:<mid>

Consensus

TermDefinition
Simplex BFTSingle-chain Byzantine Fault Tolerant consensus protocol from the Commonware library
BlockA batch of messages ordered by consensus. ~200ms block time
FinalityA block is final after two consecutive blocks are notarized (2-chain rule). ~300ms
NotarizationA 2/3+ validator vote to accept a proposed block
MempoolQueue of validated messages waiting to be included in a block

Execution

TermDefinition
Account pre-passPhase 1: serial execution of account-level messages that modify shared state
Project executionPhase 2: parallel execution of project-scoped messages grouped by project_id
Overlay storeCopy-on-write state store providing isolation between parallel project groups
Snapshot storeRead-only view of base state plus account pre-pass diffs, used as the base for overlay stores
State rootBLAKE3 merkle root combining all per-project roots in sorted order

Storage

TermDefinition
Storage unitYearly capacity allocation for an account. Default: 1 (free tier)
DA layerData availability layer — separate storage for file content (blobs, trees), referenced by da_reference in commit bundles
PruningAutomatic removal of oldest unprotected commit metadata when a project exceeds its limit. Commits referenced by active refs are never pruned
RefA named pointer (branch or tag) to a commit hash
Fast-forwardA ref update where the new commit is a descendant of the current ref target

Infrastructure

TermDefinition
CommonwareThe library of distributed systems primitives that Makechain builds on
tonicRust gRPC framework used for the API layer
rayonRust data-parallelism library used for parallel project execution
QMDBQueryable Merkle Database — planned persistent state backend