From d2e02361e9373ed6fa3c4a8c6f247e84ab4c9cd3 Mon Sep 17 00:00:00 2001 From: Daniel Polo <106583643+danielPoloWork@users.noreply.github.com> Date: Tue, 7 Jul 2026 20:24:57 +0200 Subject: [PATCH] docs(spec): add a C4 component diagram and record Mermaid as the diagram tooling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Closes the last open item of the specification review (#105): the C4 component diagram of the pool internals. The diagram is authored in Mermaid and embedded in spec §4.2; ADR-0041 records Mermaid as the in-repo diagram tooling — C4 levels are drawn as flowcharts with subgraph boundaries, and PlantUML, checked-in images, and Mermaid's experimental C4Component DSL were considered and rejected. Also cross-links the new §4.2 in the §7 spec→ADR map, un-defers the C4 item in §7.1 (now pointing at §4.2), and adds the #111 tracking ref to the benchmark-extension deferred bullet. Documentation-only; no code or API change; no version bump (rides the next release). The zh-Hans/ja spec translation rows stay stale pending the re-sync follow-up already owed from #110. Refs #105 Co-Authored-By: Claude Opus 4.8 (1M context) --- CHANGELOG.md | 10 +++ docs/adr/0041-mermaid-diagram-tooling.md | 85 ++++++++++++++++++++++++ docs/adr/README.md | 1 + docs/specs/01_spec_cpp_memory_pool.md | 54 ++++++++++++++- 4 files changed, 148 insertions(+), 2 deletions(-) create mode 100644 docs/adr/0041-mermaid-diagram-tooling.md diff --git a/CHANGELOG.md b/CHANGELOG.md index a768cd8..2b44d5d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,16 @@ under *Changed* or *Removed*. The `Unreleased` block accumulates entries during development and is rolled into a dated version block (`## [X.Y.Z] — YYYY-MM-DD`) when a release PR closes a milestone. +### Added + +- **C4 component diagram of the pool internals** in the specification + ([`docs/specs/01_spec_cpp_memory_pool.md`](docs/specs/01_spec_cpp_memory_pool.md), §4.2), + authored in Mermaid. [ADR-0041](docs/adr/0041-mermaid-diagram-tooling.md) records Mermaid + as the in-repo diagram tooling — C4 levels are drawn as flowcharts with `subgraph` + boundaries, and PlantUML, checked-in images, and Mermaid's experimental `C4Component` DSL + were considered and rejected. Closes the last open item of the specification review. + Documentation-only; no API change. Refs #105. + ### Changed - **`zh-Hans` / `ja` README translations re-synced to `v1.1.2`.** Carries the English diff --git a/docs/adr/0041-mermaid-diagram-tooling.md b/docs/adr/0041-mermaid-diagram-tooling.md new file mode 100644 index 0000000..a153044 --- /dev/null +++ b/docs/adr/0041-mermaid-diagram-tooling.md @@ -0,0 +1,85 @@ +# ADR-0041: Mermaid as the in-repo diagram tooling + +- **Status:** Accepted +- **Date:** 2026-07-07 +- **Deciders:** Daniel Polo (maintainer / project architect) +- **Related:** issue #105, spec [§4.2](../specs/01_spec_cpp_memory_pool.md#42-component-diagram-c4), [ADR-0013](0013-doxygen-for-api-markdown-for-narrative.md), [ADR-0032](0032-documentation-i18n-architecture.md) + +## Context + +The specification review (#105) asked for a **C4 component diagram** of the pool +internals. Until now the project has expressed architecture purely in prose plus one +ASCII sketch of the intrusive free list (spec §4). No diagram-authoring convention exists +yet, so adding the first real diagram forces a one-time, repo-wide decision about *how* +diagrams are authored, versioned, and rendered. + +The forces are specific to this repository: + +- **Docs are Markdown**, rendered in three places: on GitHub, in the Doxygen HTML API site + ([ADR-0027](0027-doxygen-html-site-and-publication-pipeline.md)), and mirrored by the + `zh-Hans` / `ja` translations ([ADR-0032](0032-documentation-i18n-architecture.md)). +- **Docs pay for zero build tooling.** The only doc gates are `markdownlint`, the Lychee + link check, and a dependency-free (pure-stdlib Python) consistency lint. Introducing a + renderer that needs Java, Graphviz, or a network round-trip would be a large new + dependency for a single picture. +- **A diagram must render for a reader browsing GitHub** with no local toolchain, and must + **diff cleanly** in review like the rest of the docs. + +## Decision + +We adopt **Mermaid** as the canonical in-repo diagramming tool. Diagrams are authored as +fenced ` ```mermaid ` code blocks embedded directly in the Markdown that discusses them. +GitHub renders Mermaid natively, so no build step, no checked-in raster/vector binary, and +no external renderer is introduced. For **C4-model** diagrams we express the *Component* +level as a Mermaid `flowchart` whose `subgraph` blocks delimit the C4 boundaries (system / +public surface / core engine / external store), rather than Mermaid's experimental +`C4Component` DSL. The tiny ASCII free-list sketch in §4 stays as-is — it is a byte-level +memory layout, not an architecture diagram, and reads perfectly as text. + +## Alternatives Considered + +- **PlantUML (including the C4-PlantUML macro library).** Rejected: it needs a Java + + Graphviz renderer or a server round-trip, and GitHub does not render PlantUML inline. We + would have to check in generated SVG/PNG and keep it in lockstep with its source — exactly + the silent drift the consistency lint exists to prevent, and an awkward fit for the i18n + mirrors. +- **Checked-in SVG/PNG exported from a GUI (draw.io, Excalidraw, …).** Rejected: binary + artifacts do not diff in review, go stale invisibly, and bloat the repository; there is no + textual source of truth a reviewer can read. +- **Mermaid's native `C4Component` DSL.** Rejected *for now*: it is marked experimental in + Mermaid, and its automatic layout produces overlapping, hard-to-read output for the + ~10-component diagram this project needs. A `flowchart` with explicit `subgraph` + boundaries renders reliably on GitHub and gives us layout control. The C4 *model* (its + levels, boundaries, and typed relationships) is notation-independent, so drawing it with a + flowchart is fully faithful to C4. +- **ASCII art only (the status quo).** Kept for the small in-band-pointer sketch, but + rejected as the general tool: it does not scale to a multi-component diagram with typed, + directional relationships and reads poorly beyond a handful of boxes. + +## Consequences + +- **Wins.** No new build or tooling dependency; each diagram lives next to the prose it + illustrates, diffs as plain text, and renders on GitHub, in editors (VS Code), and in + mkdocs-material-style viewers. Where Mermaid is unavailable, the reader still sees a + legible source block rather than a broken image. +- **Costs / limits.** Rendering depends on the viewer; a bare `cat` of the file shows the + Mermaid source, not a picture. Complex graphs can hit Mermaid layout quirks — mitigated by + keeping each diagram to a single C4 level and using explicit `subgraph`s for structure. +- **i18n.** A Mermaid block inside a translated source counts as source content: translators + copy it verbatim (the labels are English identifiers and pattern names) or localize the + labels, and the change is tracked like any other source edit through the + `translation-status.md` manifest. +- **Tooling / testing.** No CI change. `markdownlint` already tolerates the block (`MD013` + and `MD040` are disabled repo-wide), and the Lychee link check ignores code fences. +- **Documentation.** This ADR is the convention; the first diagram lands in spec §4.2. + Future diagrams (a Container-level view, per-subsystem sequence diagrams, …) follow the + same rule and cite this ADR. + +## References + +- The C4 model — (notation-independent architecture diagramming). +- Mermaid — and GitHub's native Mermaid rendering. +- [ADR-0013](0013-doxygen-for-api-markdown-for-narrative.md) — Doxygen for the API contract, + Markdown for the narrative. +- [ADR-0032](0032-documentation-i18n-architecture.md) — documentation i18n architecture. +- Issue #105 — specification review that requested the C4 diagram. diff --git a/docs/adr/README.md b/docs/adr/README.md index c7e7aa8..7ce8d0c 100644 --- a/docs/adr/README.md +++ b/docs/adr/README.md @@ -73,5 +73,6 @@ Do **not** write one for purely local implementation details, formatting, or tri | 0038 | [Split the changelog into one immutable Markdown file per release](0038-changelog-version-split.md) | Accepted | | 0039 | [In-repo bug ledger and agent triage protocol](0039-bug-ledger-and-triage-protocol.md) | Accepted | | 0040 | [Pull-request metadata policy (assignee, labels, milestone)](0040-pull-request-metadata-policy.md) | Accepted | +| 0041 | [Mermaid as the in-repo diagram tooling](0041-mermaid-diagram-tooling.md) | Accepted | When adding a new ADR, append a row to this table in the same PR. diff --git a/docs/specs/01_spec_cpp_memory_pool.md b/docs/specs/01_spec_cpp_memory_pool.md index 03dc7df..4fccce4 100644 --- a/docs/specs/01_spec_cpp_memory_pool.md +++ b/docs/specs/01_spec_cpp_memory_pool.md @@ -86,6 +86,54 @@ Storing a next-pointer in-band imposes constraints, all enforced by the implemen The intrusive-free-list design was chosen over a bitmap allocator; the rejected alternative and its rationale are recorded in [ADR-0009](../adr/0009-free-list-layout-block-size-constraints-and-alignment-guarantee.md). +### 4.2 Component diagram (C4) + +The C4-model **Component** view below relates the public surface, the core engine (which lives behind the opaque `memory_pool_t` handle / Pimpl), and the operating-system backing store. It is authored in Mermaid per [ADR-0041](../adr/0041-mermaid-diagram-tooling.md); a viewer without Mermaid support sees the equivalent source. Solid arrows are runtime call / ownership paths; dashed arrows are optional or diagnostic relationships. Bracketed tags name the realizing technology or the design pattern applied. + +```mermaid +%% C4 model — Component level for the pbr-cpp-memory-pool library. +%% Authored as a Mermaid flowchart with C4 boundary subgraphs (ADR-0041). +flowchart TB + app["Consumer application
[C or C++]
fixed-size allocation on a hot path"] + + subgraph lib["pbr-cpp-memory-pool — static library"] + direction TB + subgraph surface["Public surface"] + direction TB + capi["C API — memory_pool.h [extern C]
frozen 4-function ABI + create_dynamic + introspection"] + cpp["Pool / PoolBuilder [C++ RAII]
move-only owner; factory / builder construction"] + adapters["TypedPool<T> · PoolAllocator<T> [templates]
type-safe and STL-allocator adapters"] + instr["InstrumentedPool [Decorator]
counters + lifecycle Observers"] + diag["FreeListView [diagnostics, gated]
read-only free-list iterator"] + end + subgraph core["Core engine — behind the Pimpl / C ABI"] + direction TB + state["memory_pool [Pimpl struct]
backing · head · sizes · chunk list · grow factor"] + skel["alloc / free skeleton [Template Method]
range-checks, dispatches to the sync policy"] + policy["Sync policy [Strategy, compile-time]
SingleThreaded / Mutex / LockFree (ABA-tagged Treiber)"] + freelist["Intrusive free list [LIFO]
in-band next-pointer, zero per-block metadata"] + chunks["Chunk list [Composite]
non-contiguous geometric growth; pointers stay valid"] + end + end + + os[("Backing storage
[over-aligned operator new]
alignof(max_align_t)")] + + app -->|"C ABI"| capi + app -->|"idiomatic C++"| cpp + adapters -->|"compose"| cpp + instr -.->|"decorate"| cpp + diag -.->|"iterate (gated)"| freelist + cpp -->|"own via C core"| capi + capi --> state + state --> skel + skel -->|"pop / push"| policy + policy --> freelist + skel -->|"grow on exhaustion"| chunks + chunks -->|"seed a sub-list"| freelist + chunks --> os + state --> os +``` + --- ## 5. API / Public Interface @@ -171,6 +219,7 @@ Every requirement above is realized and recorded. The table maps the spec to its | §2.4 thread safety (mutex / lock-free + ABA tag) | [ADR-0020](../adr/0020-thread-safety-strategy-and-compile-time-knob.md) | | §3.2 overhead budget & introspection | [ADR-0015](../adr/0015-metadata-overhead-budget-and-introspection.md) | | §4 free-list layout, constraints, alignment, intrusive-vs-bitmap | [ADR-0009](../adr/0009-free-list-layout-block-size-constraints-and-alignment-guarantee.md) | +| §4.2 component (C4) diagram & diagram tooling | [ADR-0041](../adr/0041-mermaid-diagram-tooling.md) | | §5.1–5.2 API, RAII, Pimpl, builder, typed pool, STL adapter | [ADR-0010](../adr/0010-raii-pool-wrapper-and-pimpl-across-the-c-cpp-boundary.md), [ADR-0011](../adr/0011-factory-method-and-builder-for-pool-construction.md), [ADR-0017](../adr/0017-typed-pool-design.md), [ADR-0018](../adr/0018-stl-allocator-adapter.md) | | §5.3 error semantics | [ADR-0012](../adr/0012-foreign-pointer-and-out-of-range-pointer-policy.md), [ADR-0016](../adr/0016-exception-policy-at-the-c-cpp-boundary.md) | | §5.4 instrumentation / observers | [ADR-0025](../adr/0025-decorator-for-instrumented-pool.md), [ADR-0026](../adr/0026-observer-for-pool-lifecycle-events.md) | @@ -184,5 +233,6 @@ These are explicitly out of the current build and tracked as issues: - **`std::pmr::memory_resource` adapter** — the "door left open" in [ADR-0018](../adr/0018-stl-allocator-adapter.md) (issue #107). - **Coverage-guided fuzzing harness** (issue #108). - **Opt-in debug hardening** — freed-block poisoning, canaries, free-list safe-linking; would also add double-free detection (issue #109). -- **Benchmark extension** — external baselines (jemalloc/tcmalloc) and p99 percentile reporting. -- **C4 component diagram** of the pool internals. +- **Benchmark extension** — external baselines (jemalloc/tcmalloc) and p99 percentile reporting (issue #111). + +The **C4 component diagram** of the pool internals, once deferred here, now ships in [Section 4.2](#42-component-diagram-c4) (its tooling decision is [ADR-0041](../adr/0041-mermaid-diagram-tooling.md)).