Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 75 additions & 0 deletions .claude/diagrams.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# Diagrams

When and how to draw diagrams in technical docs.

## When to draw a diagram

A diagram earns its place when it shows a topology, a flow, or a state machine that prose would describe more poorly. Decorative diagrams that just rephrase the surrounding paragraph are noise — cut them.

Three patterns that genuinely need a diagram:
- **Topology** — components and their static relationships (architecture overviews, layered models).
- **Sequence** — message flow across actors over time, especially with branching.
- **State / pipeline** — staged process with conditional transitions.

Anything else, prefer prose.

## Tooling: SVG vs Mermaid vs static images

**SVG (handcrafted)** — preferred for architecture diagrams. Predictable rendering at any container width, no plugin dependency, exact control over typography and color, diff-able as text. The cost is one-time authoring effort.

**Mermaid** — convenient for quick draft diagrams, but rendering quality depends on the host site's CSS, container width, and theme. Text overflows boxes, edge labels truncate, and the rendering engine evolves between versions. For a docs site where rendering control matters, Mermaid is a footgun in production.

**Static images (PNG/JPG)** — reasonable for screenshots, wireframes, and illustrations that aren't generated from code. Bad for architecture diagrams because they don't respond to dark/light theme, can't be edited by a contributor without the source file, and bloat the repo.

Default to SVG for architecture and pipeline work. Use Mermaid only if the page is throwaway or the diagram is so simple its rendering is uncontroversial.

## The draft → final pattern

Mermaid (or even ASCII art) is a useful **drafting medium** even when the final diagram will be SVG. Mermaid lets you iterate on structure with the user quickly — boxes, arrows, branching — without paying SVG authoring cost up front. Once the structure is locked, convert to handcrafted SVG with the project's palette.

The pattern:

1. Sketch structure in Mermaid in chat or the markdown source. Get user agreement on what goes in the diagram and how it branches.
2. Author the SVG with the agreed structure plus the project's standard palette, marker, and viewBox.
3. Replace the Mermaid block with `![alt](/img/<section>/<name>.svg)`.

Skipping the draft step often produces SVGs that need to be re-authored after user feedback on structure. Keep the cheap iteration loop cheap.

## Style consistency within a section

Every diagram in a section should share:
- **Background**: transparent (`fill="none"` on the root `<svg>`) so dark-themed sites show through.
- **Stroke palette**: one neutral color for box and arrow strokes, never multiple competing colors. Reserve color for emphasis only.
- **Text hierarchy**: titles at one weight/size, subtitles at one weight/size lighter. Two tiers max.
- **Marker definition**: one shared arrowhead marker referenced by every line, not per-arrow inline definitions.
- **Stroke width**: consistent — typically 1.5px for everything.

Inconsistency reads as low-effort.

## Conditional vs sequential flows

Solid lines are for the happy path. Dashed lines (typically `stroke-dasharray="5,5"`) are for conditional, alternative, or unresolved transitions. Label both — readers should not have to infer which is which.

For state-machine diagrams, sequential transitions are solid; "if this fails" or "if disputed" branches are dashed.

## Sequence diagrams

For sequence diagrams done in raw SVG:
- Actors as boxes across the top, lifelines as dashed verticals running down.
- Messages as horizontal arrows with the message label centered above.
- Self-loops as a three-segment path going right, down, back to the lifeline with arrowhead.
- Branching alternatives separated by a dashed horizontal line, each branch labeled in italic.

Don't try to mimic UML alt/opt boxes precisely — the visual overhead beats the clarity gain.

## Sizing for site container

Pick a viewBox sized for typical content container width. Most docs sites render content in a ~720–900px column. A diagram with viewBox `0 0 1000 500` will scale to ~80% in that container, shrinking text from 14pt to ~11pt — readable but tight.

If text becomes hard to read at site width, the diagram has too much in it. Cut elements or split into two diagrams. Don't fight the container by making the SVG larger.

## What to never put in a diagram

- Constants and addresses that change between releases — they belong in the surrounding prose where a single edit fixes them.
- Long descriptive paragraphs in box labels — boxes hold names and short qualifiers, not sentences.
- Color-coded states without a legend — readers won't infer what red vs green means.
50 changes: 50 additions & 0 deletions .claude/voice.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# Voice

Tone and style rules for technical documentation written for engineers and auditors.

## Target audience and tone

Public technical docs are read by infra/protocol engineers, security auditors, and careful application developers. Write as a senior engineer who has shipped the system in question — direct, calm authority, no marketing flex. Not a tutorial author explaining concepts from first principles, not a developer advocate selling a feature.

The reader does not need to be told they are about to read documentation. They do not need a "what this section covers" preamble. They need facts, mechanism, and the boundaries that hold the mechanism together.

## Anti-patterns to strip

These are the LLM tells that make documentation read as machine-generated. Strip every instance during writing or in a dedicated revision pass.

1. **Meta-narration** — "this section explains…", "the point of this is…", "what matters here is…", "the important thing to understand…".
2. **Reflexive triads** — "X, Y, and Z" when one or two items would do; symmetric three-bullet lists at every section end.
3. **Filler hedges** — "it is worth noting", "it is important to understand", "one key thing", "the subtle thing to remember".
4. **False summaries** — "in essence", "ultimately", "in short", "simply put", "at a high level".
5. **Corporate abstractions** — "uniformly", "coherently", "seamlessly", "robustly".
6. **Hype adjectives** — "powerful", "elegant", "beautiful", "novel", "cutting-edge".
7. **Overused copulative patterns** — "X is what Y" where an active verb works; "the {noun} is {verb}ing {noun}" rhythm across consecutive sentences.
8. **Self-referential navigation** — "the rest of this section explains…", "this page walks you through…" when the sidebar already does that work.
9. **Pseudo-authoritative hedging** — "it should be noted that…", "one could argue that…", "generally speaking…".
10. **LLM signposts** — "let's explore…", "consider the following…", "imagine that…".
11. **Repetition for rhetoric** — saying the same point three times with different wording. Say it once.

## Concrete grounding

Narrative prose is fine; ungrounded narrative is not. Every meaningful claim should land on a concrete anchor — a constant name, an address, a method signature, a chain ID, a magic value. The anchor is what makes the page useful for reference; the prose is what makes it readable.

Bad: "The bridge has a deposit deadline that admins can configure."
Better: "The L1-owned `_depositProcessingWindow` is snapshotted into each outbound deposit at send time and bounded at `MAX_DEPOSIT_PROCESSING_WINDOW = 50_400` blocks."

If a fact comes from contract source, prefer the literal name (`commitBatch`, `_rollupCorrupted`, `FUEL_DENOM_RATE = 20`) over a paraphrase. Code rot beats narrative rot — when the constant is renamed, the diff is obvious.

## ASCII conventions

Use ASCII apostrophes (`'`) and ASCII quotes (`"`) throughout. Smart punctuation (`'`, `'`, `"`, `"`) breaks search, copy-paste of code-adjacent text, and creates noisy diffs when editors auto-correct. The exception is when the source you are quoting must be preserved character-faithful — then call it out explicitly.

## Cross-link patterns

A trailing "See [X]" link at the end of an entry is more useful than inline links scattered through prose. It signals "for the full picture, here". Inline links work when the linked page genuinely interrupts the current sentence ("the [interruption protocol](...) handles this"), but should be rare.

Glossary-style entries should close with one canonical link to the deeper page. Never link to multiple destinations from a single entry — the reader picks none.

## Length discipline

Length is a budget, not a target. Every paragraph should earn its existence. Default question before adding a paragraph: "if I removed this, would the reader miss anything they couldn't get from the prior paragraph or a linked page?" If no, cut it.

Short pages with high information density beat long pages padded with explanation. Treat 1500 words as the upper bound for a single architecture page; cut harder if you can.
61 changes: 61 additions & 0 deletions .claude/workflow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# Workflow

How to approach a docs task end-to-end.

## Source-of-truth grounding before drafting

Before writing prose, locate the authoritative source for what you are documenting. For protocol/contract docs that means the contract source itself, plus any upstream docs the team treats as canonical (often a separate repo synced locally for reference). Read the source first, draft second.

If the authoritative source is in flux or contradicts the docs you are about to write, stop. Document divergence is worse than no documentation — it actively misleads.

When the source lives outside the repo and is not committed (e.g. a local sync of an upstream docs/), reference that constraint explicitly so the agent knows facts come from there, not from the public site.

## Voice as a separate revision pass

Drafting and voice-polishing are different skills and should be different passes. First draft: get the facts right, get the structure right, hit the concrete anchors. Don't worry about LLM tells.

Then run a dedicated **de-AI pass** with the anti-pattern list from `voice.md` open as a checklist. Strip meta-narration, hedges, false summaries, hype. This pass is voice-only — facts, structure, admonitions, links, diagrams, frontmatter all stay byte-identical.

Combining the passes produces neither — facts get bent to fit the prose, prose gets bent to fit the facts.

## Fact-check after voice pass

A voice rewrite that touches every paragraph is exactly when you can accidentally weaken a claim ("could commit" → "commits") or drop a precision ("X is the load-bearing field" → "X is the field"). After de-AI, do a fact-check pass against the diff: is every concrete anchor preserved? Did any modal verb get stronger or weaker than the source supports?

This is the cheapest place to catch drift. Once committed, drift compounds.

## Build verification gate

Run the site's build command after every meaningful change. For Docusaurus and similar generators, broken internal links and missing assets fail the build only when explicitly configured (`onBrokenLinks: "throw"`). Confirm that gate is on, then run the build before claiming any docs change is done.

A build that "should work" because nothing structurally changed has lost the team an hour of bisecting later. Run it.

## Single-concept commits

A commit that adds a new page, fixes voice across three other pages, and renumbers the sidebar mixes three reviewable concerns into one diff. Split:

- New content → its own commit.
- Voice/style revisions → its own commit.
- Mechanical reshuffles (sidebar positions, file renames) → either folded into the change that requires them, or their own commit.

Reviewers evaluate one concern per commit; mixed commits force them to evaluate all three at once and approve none confidently.

## Tone preservation when revising existing pages

When editing a page someone else wrote, preserve their voice unless the user has asked for a global tone change. Resist the impulse to "improve" prose that already works just because it's not exactly how you would have written it. Editors who rewrite for taste burn maintainer trust faster than they add value.

The exception is documented anti-patterns (LLM tells, false summaries, hype) — those are bugs, not stylistic preferences.

## Cross-reference audit after adding or renaming content

A new page or a renamed slug does not exist in isolation. After the change, walk through the predictable places that might need to point at it:

- **Sidebar and navigation metadata** — does the new page have a `sidebar_position` that does not collide with siblings? Did renaming break a parent folder's category config?
- **Landing pages and discovery cards** — front pages, "what's next" cards, hero-section links often hardcode their targets. The new page is invisible if nothing on the entry-point pages routes a reader to it.
- **Glossary** — terms introduced in the new page may already have entries elsewhere; if not, consider adding short entries that point at the new page. Existing glossary entries on related concepts should mention the new page in their trailing "See [X]" link if it now offers a deeper home.
- **Adjacent topic pages** — pages on neighbouring topics often reference each other. A new page on topic X should be discoverable from pages on topic Y where a reader would naturally want the link.
- **External tooling that depends on URL stability** — search-index configs, redirect rules, social-share previews. A renamed slug breaks these silently because the build's broken-link checker only sees what is in the repo.

The build's broken-link checker catches dead links. It does not catch *missing* links — places where a reader would expect a reference but none exists. Audit by hand: read the affected pages from the perspective of someone arriving at them via the most likely entry point, and ask whether they would discover the new content.

For renames specifically, grep the entire `docs/` tree for the old slug before assuming it is only referenced where you remember it.
8 changes: 7 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,10 @@ yarn-debug.log*
yarn-error.log*

# IDE
.idea
.idea

# Claude Code
# Per-developer state stays local; shared standards (.claude/*.md) and CLAUDE.md are committed.
.claude/tasks/
.claude/settings.local.json
fluentbase-docs/
68 changes: 68 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# Fluent Docs (Docusaurus)

Public documentation site for Fluent, published at https://docs.fluent.xyz. Built with Docusaurus 3.9.

## Build & Test

- `npm run start` — local dev server on port 8000
- `npm run build` — production build. **Required gate before commit**: fails on broken internal links via `onBrokenLinks: "throw"` in `docusaurus.config.js`.
- `npm run serve` — preview the production build locally
- `npm run clear` — clear Docusaurus cache when the build behaves oddly

## On every task

- Read `.claude/voice.md`, `.claude/workflow.md`, `.claude/diagrams.md`

These are committed to the repo so every contributor (and their AI assistants) follows the same rules. If you maintain personal cross-project standards in `~/.claude/standards/docs/`, the in-repo files are the project-canonical version — drift from your personal copy is allowed and expected.

This is a docs-only repository. Generic code standards are not auto-loaded — almost every task here is content/structure, not application code. If a task does touch `docusaurus.config.js`, custom plugins, or `src/` SCSS, ask whether broader code-style rules apply.

### Site facts

- **Published URL**: https://docs.fluent.xyz
- **Theme**: dark only — `colorMode.defaultMode: "dark"` and `disableSwitch: true` in `docusaurus.config.js`. Diagrams and content must read on a dark background.
- **Sidebar**: auto-generated from the `docs/` filesystem (`sidebars.js`). Ordering is controlled by `sidebar_position` frontmatter on individual pages and `_category_.json` `position` per folder. Verify positions don't collide with siblings when adding entries.
- **Source-of-truth for protocol/contract behavior**: `fluentbase-docs/` directory at repo root, mirrored from `https://github.com/fluentlabs-xyz/fluentbase/tree/devel/docs`. Not committed (gitignored). Use as the authoritative reference when documenting rollup, bridge, or runtime mechanics.

### Filename and URL conventions

- **Bare slugs only** for content files in `docs/` — no `NN-` numeric prefixes (e.g. `overview.md`, not `01-overview.md`). Sidebar order goes through frontmatter; the URL is the file slug.
- New section folder: include `_category_.json` with `label`, `position`, and `collapsed`. Verify the `position` against siblings.
- New top-level page: bump `sidebar_position` on trailing pages (glossary, resources, contribute) to keep numbering contiguous.

### Diagrams

- **Mermaid is installed** (`@docusaurus/theme-mermaid@3.9.2`, `markdown.mermaid: true`) but **not used** for architecture diagrams. Mermaid renders poorly at the site's container width — node and edge labels truncate. Use handcrafted SVG instead.
- SVGs live in `static/img/<section>/`, referenced from markdown as `/img/<section>/<name>.svg`.
- Style palette tuned for this dark theme: stroke `#cccccc` 1.5px, primary text `#ffffff` font-weight 600, subtitles/metadata `#a0a0a0` (italic where appropriate), `fill="none"` on every shape so the dark background shows through. One shared arrowhead marker per file.
- Dashed `stroke-dasharray="5,5"` for conditional / unresolved transitions. Solid lines for the happy path.
- **Workflow for new diagrams**: sketch first in Mermaid (or ASCII art) for fast structural iteration with the user. Once the structure is approved, convert to handcrafted SVG with the palette above. Don't ship Mermaid — only use it as a draft medium because the live render at this site's container width truncates labels.
- See `~/.claude/standards/docs/diagrams.md` for general diagram principles.

### Admonitions

Whitelisted keywords (from `docusaurus.config.js:48-59`): `tip`, `prerequisite`, `warning`, `info`, `danger`, `best-practice`, `summary`. Use only when the admonition carries real meaning — not as cosmetic emphasis.

### Cross-link conventions

Internal links use relative `.md` paths. Within a section: `[Execution Model](./execution-model.md)`. Across sections: `[Blended 101](../knowledge-base/blended-101.md)`. Glossary entries close with one trailing `See [X]` link to the deeper page.

### Cross-reference audit (after adding or renaming a page)

The build's `onBrokenLinks: "throw"` catches dead links but not *missing* references. After every content change, walk these predictable hotspots in this repo:

- `docs/get-started.md` — landing-page cards (table block + div-view-cards block) hardcode their targets. A new top-level section is invisible if nothing here routes to it.
- `docs/glossary.md` — terms introduced by the new page may already have entries; if not, consider adding one. Existing entries on adjacent concepts should point at the new page in their trailing `See [X]` link if it is now the deeper home.
- `docs/knowledge-base/blended-101.md` and `docs/knowledge-base/fluent-overview.md` — concept pages that frequently reference architecture pages.
- Sibling pages inside the same section — system-architecture pages cross-reference each other heavily.
- `_category_.json` files — when adding a new top-level folder, verify `position` against siblings to avoid Docusaurus tie-break ordering.

When renaming a slug, `grep -rn "<old-slug>" docs/` before assuming you have caught every reference.

See `.claude/workflow.md` for the underlying principle.

## Security

- Never read files listed in .gitignore, except `.claude/` directory
- Never read .env, .env.*, *.pem, *.key, *secret*, *credential* files
- If a task requires secrets — ask the human to provide only the specific value needed
Loading
Loading