Skip to content

Writing Documentation

Conflux documentation follows the Diataxis framework. Every page belongs to exactly one of four types. Match the type to the reader's need, not the subject matter. For a full explanation of the framework and why Conflux uses it, see The Diataxis Framework.

Choosing a Type

Ask yourself two questions:

  1. Is the reader learning or doing? → Tutorial (learning) / How-to (doing)
  2. Are they looking something up or wanting to understand? → Reference (lookup) / Explanation (understand)

A single subject may need all four types as separate pages.

Tools

Tool Purpose Output
Zensical General docs (guides, concepts, reference, tutorials) docs/docs/ → rendered site
Scribe API reference Auto-generated via php artisan scribe:generate

File & Navigation Conventions

  • File names: kebab-case.md
  • Place pages in a logical subfolder under docs/docs/ (e.g. explanation/frameworks, how-to-guides/, reference/)
  • Navigation is derived from folder structure — no manual config needed unless ordering matters
  • Page title = first # H1 heading

Markdown Conventions

Zensical supports Material for MkDocs extensions.

Admonitions

!!! note "Optional title"
    Content here.

!!! warning
    Types: note, tip, info, success, warning, danger, failure, bug, example, quote

Tabbed content

=== "Tab one"
    Content for tab one.

=== "Tab two"
    Content for tab two.

Code blocks with line numbers

```php linenums="1"
// code here
```

Scribe: Documenting API Endpoints

Scribe generates API docs from controller docblocks. Do not write manual Markdown pages for endpoints — add docblocks to the controller method instead, then regenerate:

docker compose exec php php artisan scribe:generate

Common annotations:

/**
 * @group Orders
 * @authenticated
 *
 * @bodyParam shop_id string required The shop UUID. Example: 01HXYZ...
 *
 * @response 200 {"id": "01HXYZ...", "status": "pending"}
 */
public function store(StoreOrderRequest $request): OrderResource

Architecture Decision Records (ADRs)

Significant architecture decisions — a new entity, a changed data-flow direction, an auth model change, anything a future reader would ask "why was it built this way?" about — get an ADR instead of an inline narrative admonition.

  • Location: docs/docs/adr/
  • Naming: 4-digit zero-padded sequence + present-tense-imperative kebab-case title
  • Template: Nygard-style — Date + Status, then Context / Decision / Consequences. No frontmatter (ADRs are not a Diataxis type).
  • An ADR is superseded, never edited in place: a changed decision gets a new ADR, and the old one is marked Status: Superseded by 00NN.
  • Add new ADRs to the nav in zensical.toml under "Decisions" — the nav is the single listing; docs/docs/adr/index.md stays a short intro, like explanation/index.md and how-to-guides/index.md.

What the gate enforces

The conventions above are checked automatically, so a forgotten nav entry or a number taken twice on parallel branches fails before it reaches master. Failure messages name the file and the rule number:

Rule Checked
1 Filename matches NNNN-kebab-case.md
2 Numbers are unique
3 Numbers are contiguous from 0001
4 The H1 number matches the filename
5 Date: YYYY-MM-DD is present and real
6 Status: starts with Accepted, Proposed, Deprecated, Superseded by or Partially superseded by
7 An ADR referenced by a status exists
8 Context, Decision and Consequences are all present
9 There is no frontmatter
10 Every ADR has exactly one nav entry, and every entry points at a file that exists
11 Nav entries are ordered and labelled by number, with adr/index.md first
12 A number added in a merge request is not already taken on the target branch

Rules 1 to 11 run in tests/Unit/Docs/AdrTest.php, so composer test catches them locally. Rule 12 runs as .gitlab/scripts/check-adr-numbers.sh in the quality stage: a branch that adds a duplicate number is internally consistent on its own, so only a comparison against the target branch can see the collision.

Rule 3 means a number cannot be skipped. If an ADR is drafted and dropped, either reuse its number for the next decision or adjust the test — a gap is not silently tolerated, because the common cause of one is a mistake.