Document Generation
Tipos de documento gerados por categoria de objeto (Stack, Area, Sector, Module, Flow, RFC), requisitos de capa, regras de identidade visual e templates CSS para PDFs. Consultado no início da Fase 3 do `/k-housekeep`.
Spec: Document Generation
*cope:*Defines which document types are generated for each category of Koder Stack object (Stack, Area, Sector, Module, Flow, RFC), cover page requirements, and visual identity rules for generated PDFs.
*nforcement:*/k-housekeep Phase 3 reads this spec and generates or updates the full PDF bundle accordingly.
1. Object categories
The Koder Stack has five object categories that drive documentation generation. Each category has a fixed set of document types (see §2).
| Category | Definition | Examples |
|---|---|---|
| *tack* | The entire Koder Stack as a whole | — |
| *rea* | One of the 9 canonical Areas (docs/stack/areas.md) |
Foundation, Data Platform, Workspace … |
| *ector* | A named grouping of related modules within an Area (second column in areas.md) |
Koder Linux, KDB, Edge/Jet, Intelligence … |
| *odule* | Any active module in the monorepo (see areas.md rows, third column) |
platform/id, infra/jet, apps/keys … |
| *low* | A named cross-cutting flow that spans two or more Areas (docs/stack/diagrams/flows/) |
auth flow, data-write flow, AI inference flow … |
2. Document types per category
2.1 Stack
| Document | Format | Source / Generator |
|---|---|---|
| Technical Reference | PDF (A4, Typst) | docs/stack/build/technical.typ → out/koder-stack-technical.pdf |
| Executive Slides | PDF (A4, Typst) | docs/stack/presentation/slides/main.typ → out/koder-stack-slides.pdf |
2.2 Area
One set of documents per Area (9 total). Output folder: <N>-<area-slug>/ in the bundle.
| Document | Format | Content |
|---|---|---|
| *rea Slide Deck* | PDF (A4 landscape, WeasyPrint) | Cover + module inventory (one card per module: icon, name, one-line description) + flows & integrations diagram + integration map (which modules call which) + sector breakdown |
| *rea Deep-Dive* | PDF (A4 portrait, WeasyPrint) | Cover + Area description + Sector table + per |
| *rea Diagrams* | PDF (A4 landscape, WeasyPrint) | One page per diagram file under docs/stack/diagrams/areas/<area>.d2 (rendered via d2 --theme 0) |
2.3 Sector
One set of documents per Sector row in areas.md. Output folder: <N>-<area-slug>/sectors/<sector-slug>/.
| Document | Format | Content |
|---|---|---|
| *ector Slide Deck* | PDF (A4 landscape, WeasyPrint) | Cover + module list (icon, name, one-line description for each module in the sector) + integration diagram within the sector + relationships to other sectors |
| *ector Overview* | PDF (A4 portrait, WeasyPrint) | Cover + what the sector does + why it's grouped + module summaries + typical data flows within the sector |
2.4 Module
One set per active module. Output folder: <N>-<area-slug>/<module-name>/.
| Document | Format | Content |
|---|---|---|
| *eep-Dive* | PDF (A4, WeasyPrint) | docs/stack/modules/<module>.md — role, couplings, interfaces, status |
| *FC(s)* | PDF (A4, WeasyPrint) | Each .md / .kmd under <module>/docs/rfcs/ |
| *anual(s)* | PDF (A4, WeasyPrint) | Each .md under <module>/docs/technical/, <module>/docs/user/, <module>/docs/operator/ |
| *lide Deck* | PDF (A4 landscape, WeasyPrint) | Cover + what it does + architecture overview + key interfaces + status + roadmap (sourced from README + deep-dive) |
| *EADME* | PDF (A4, WeasyPrint) | <module>/README.md or <module>/README.kmd |
| *HANGELOG* | PDF (A4, WeasyPrint) | <module>/CHANGELOG.md if it exists |
RFCs and Manuals may not exist for every module — skip silently if source files are absent.
2.5 Flow
One document per flow diagram file under docs/stack/diagrams/flows/.
| Document | Format | Content |
|---|---|---|
| *low Diagram* | PDF (A4 landscape, WeasyPrint) | Cover + rendered D2 diagram + written description of the flow (from companion .md if present, else auto-generated from diagram node labels) |
3. Cover page specification
*very generated PDF must start with a cover page.*No exceptions.
3.1 Cover page layout (portrait documents)
┌─────────────────────────────────────────────┐
│ │
│ [icon 96×96 px, centered] ← Module only │
│ │
│ ──────────────────────────────────── │
│ KODER STACK │ ← brand line, 10pt, #94a3b8
│ <Area / Sector / Module / Flow name> │ ← category label, 10pt, #64748b
│ │
│ <Document Title> │ ← 28pt bold, #0f172a
│ │
│ <subtitle / tagline — one line> │ ← 14pt, #475569
│ │
│ ──────────────────────────────────── │
│ │
│ <Status badge if applicable> │ ← e.g. "Pre-Alpha", "Draft"
│ <Date> · Koder │ ← 9pt, #94a3b8
│ │
└─────────────────────────────────────────────┘3.2 Cover page layout (landscape documents — slide decks, diagrams)
Same structure as portrait but centred horizontally on an A4 landscape page. Icon is 128×128px.
3.3 Icon placement rules
- *odule documents* the module's
icon.svg(rasterised to 96px for portrait, 128px for landscape) appears *entred above the title*on the cover page. Areafirst products (RFC001) may keep the canonicalicon.svgat the product root (<area>/<product>/icon.svg) or at a distribution root (<area>/<product>/platform/icon.svg,<area>/<product>/app/icon.svg,<area>/<product>/app/<surface>/icon.svg). The generator resolves deepestfirst for files inside a subproduct, falling back to the product root — it must never substitute the Koder brand mark when a module-localicon.svgexists anywhere in the product tree. - *rea documents* use the area's representative icon if one exists under
docs/stack/presentation/assets/icons/<area-slug>.svg; otherwise use the Koder brand mark (meta/brand/koder-papelaria/koder-marca.svgscaled to 96px). - *ector documents* use the first module icon of the sector (alphabetical by module path) as representative icon.
- *tack documents* use the Koder brand mark.
- *low documents* use the Koder brand mark.
*randfallback policy.*The Koder brand mark may only be used as a cover icon for *tack* *rea* and *low*documents. For any *odule*document, if no module icon bugs in the catalogue.icon.svg can be located, the generator must render the cover page *ithout any icon*rather than substitute the Koder mark. Logging a warning is mandatory; silent substitution hides missing
3.4 Icon in document body (first content page)
For *odule documents only* on the first content page (immediately after the cover), place the module icon inline at the *eft of the document title heading*(<h1>). Implemented in the HTML template as:
<h1 class="doc-title">
<img src="{icon_path}" class="title-icon" alt="">
{document_title}
</h1>.doc-title { display: flex; align-items: center; gap: 14px; }
.title-icon { width: 48px; height: 48px; flex-shrink: 0; }This applies to: Deep-Dive, RFC, Manual, README, CHANGELOG, and Slide Deck (first slide title).
4. Content requirements per document type
4.1 Area Slide Deck — required slides
- Cover (§3)
- "What is <Area>?" — 3
5 sentences, area ruleof-thumb - Sector map — one row per Sector: sector name + modules in it (pill list)
- Module cards — one slide per module: icon (64px) + name + one-line description + status badge
- Integration map — which modules depend on which (generated from deep-dive coupling tables)
- Key flows — one slide per flow that is internal to this Area
- Connections to other Areas — list of cross-area dependencies
4.2 Module Slide Deck — required slides
- Cover (§3, with module icon 128px centred)
- "What is <Module>?" — role, one-paragraph description
- Architecture overview — diagram (embed
docs/stack/diagrams/modules/<module>.d2if present, else text-based) - Primary couplings — table: dependency | purpose | protocol
- Interfaces — APIs, CLI commands, config keys (from deep-dive Interfaces section)
- Status & roadmap — status badge + 3-5 bullet points from backlog/STATUS
4.3 RFC — required sections
RFCs are author-written; the generator does *ot*synthesise content. The generator only:
- Adds the cover page (§3)
- Adds the module icon to the first
<h1>(§3.4) - Reformats for A4 margins and page numbering
If an RFC source file already has a cover section (frontmatter with title:, status:, date:), extract those values for the cover page instead of inferring.
4.4 Manual — required sections
Same as RFC rule: generator adds cover + icon + layout, does not synthesise content.
5. Source → output mapping
The generator traverses these source locations in priority order for each module:
<module>/icon.svg → cover icon, h1 icon
<module>/README.md → README.pdf
<module>/README.kmd → README.pdf (prefer over .md if both exist)
<module>/CHANGELOG.md → CHANGELOG.pdf
<module>/STATUS.md → included in Slide Deck slide 6
<module>/docs/rfcs
src/**/*.kmd` — source-embedded documentation (not standalone docs)
- `**/.koder-rules
.changeset/**` — release automation metadata
- `**/backlog
node_modules/**`, `**/vendor/**`, `**/target/**` — generated artefacts
**Top-level module filter:** For READMEs and CHANGELOGs, only include files at depth `<area>/<module>/README.{md,kmd}` and `<area>/<module>/CHANGELOG.md` (i.e., module root level). Sub-package READMEs (e.g. `platform/kdb/next/README.md`) are excluded unless the sub-package is itself listed as a distinct module in `areas.md`.
### 10.2 Document type table
| Code | Type | Source pattern(s) | Quantity (surveyed) |
|---|---|---|---|
| **OVW** | Overview / Deep-Dive | `docs/stack/modules
docs/rfcs/*.{md,kmd}` · `docs/stack/rfcs/**/*.{md,kmd}` | ~46 |
| **ARC** | Architecture | `**/docs/technical/architecture*.md` · `**/docs/technical/flows*.md` · `docs/stack/diagrams*.d2` | ~25 |
| **REF** | Reference | `**/docs/technical/api-reference*.md` · `**/docs/technicaldocs/technical/protocols*.md` · `**/docs/technical/configuration*.md` | ~30 |
| **OPS** | Operations | `**/docs/technical/infrastructure*.md` · `**/docs/technical/dependencies*.md` · `**/docs/technical/security*.md` · `**/docs/operator
docs/user/*.md` · `**/docs/technical/user-*.md` | ~10 |
| **REL** | Release / Changelog | `<module>/CHANGELOG.md` (root only) · `<module>/STATUS.md` | ~50 |
| **SLD** | Slides / Presentation | `docs/stack/presentation/slides/main.typ` · synthesised per-area, per-module slide decks | 1 Typst + N synthesised |
| **GOV** | Governance | `<module>/CONTRIBUTING.{md,kmd}` · `<module>/CODE_OF_CONDUCT.{md,kmd}` · `<module>/SECURITY.{md,kmd}` | ~24 |
| **BKL** | Backlog | `**/backlog/{pending,in-progress,done}
.cover { page-break-after: always; display: flex; flex-direction: column;
align-items: center; justify-content: center; min-height: 25cm;
text-align: center; }
.cover-brand { font-size: 10pt; color: #94a3b8; letter-spacing: .1em;
text-transform: uppercase; margin-bottom: 4px; }
.cover-cat { font-size: 10pt; color: #64748b; margin-bottom: 24px; }
.cover-icon { width: 96px; height: 96px; margin-bottom: 24px; }
.cover-title { font-size: 28pt; font-weight: 700; color: #0f172a;
line-height: 1.15; margin-bottom: 12px; }
.cover-sub { font-size: 14pt; color: #475569; margin-bottom: 32px; }
.cover-line { width: 60%; border-top: 1px solid #e2e8f0; margin: 0 auto 20px; }
.cover-meta { font-size: 9pt; color: #94a3b8; }
h1.doc-title { display: flex; align-items: center; gap: 14px;
font-size: 21pt; color: #0f172a; }
h1.doc-title .title-icon { width: 48px; height: 48px; flex-shrink: 0; }12. Screenshot capture for UI modules
Screenshots of module UIs are embedded in Manuals (USR and REF documents) and in Module Slide Decks. This section defines how they are captured, stored, named, and embedded.
12.1 Scope — which modules get screenshots
Screenshots apply only to modules that have a userfacing UI. The generator autodetects by checking:
| Signal | Inferred platform |
|---|---|
<module>/pubspec.yaml exists |
Flutter app (desktop + mobile + optionally web) |
<module>/site/ exists with a running URL |
Web app |
| Both | Flutter app with web companion |
| Neither | No UI — skip screenshot capture entirely |
Modules that *ever*get screenshots: SDKs (sdk/), CLIs, infra (infra/), data engines (data/), pure backend services with no web UI.
12.2 Storage location
All screenshots live at:
<module>/docs/assets/screenshots/
├── web-desktop/ ← Playwright, 1440×900
│ ├── 01-home.png
│ ├── 02-login.png
│ └── …
├── web-tablet/ ← Playwright, 768×1024
│ └── …
├── web-mobile/ ← Playwright, 390×844 (iPhone 14 viewport)
│ └── …
├── desktop-linux/ ← Xvfb + flutter run -d linux
│ └── …
├── mobile-android/ ← AVD + flutter run / adb screencap
│ └── …
└── screenshots.yaml ← optional: captions + navigation stepsScreenshots are *ommitted to the repo*— they are source assets, not build artefacts. The capture pipeline regenerates them on demand (not on every housekeep — see §12.6).
12.3 Naming convention
Files are named NN-<screen-slug>.png where NN is a two-digit sequence number that controls display order in the document:
01-home.png
02-login.png
03-dashboard.png
04-settings.pngCaption is derived from the filename: 02-login.png → "Login", 03-user-dashboard.png → "User dashboard". Override via screenshots.yaml (see §12.5).
12.4 Automated capture pipeline — per platform
12.4.1 Web (Playwright)
Requirements: playwright Python package, Chromium browser installed.
for each viewport in [desktop(1440,900), tablet(768,1024), mobile(390,844)]:
folder = web-desktop | web-tablet | web-mobile
1. Launch Playwright Chromium (headless)
2. Navigate to module URL (from koder.toml → url, or inferred from site/ hostname)
3. Wait for networkidle
4. Capture full-page screenshot → 01-home.png
5. If screenshots.yaml has navigation steps, execute each step and capture
6. Save to <module>/docs/assets/screenshots/<folder>/Mobile viewport uses device_scale_factor=2 (retina). If a step requires login, use the test account from meta/context/credentials/ (never hardcode in spec).
12.4.2 Desktop — Flutter Linux (Xvfb)
Requirements: Xvfb, scrot, flutter SDK, module must compile for Linux.
1. Start Xvfb on display :99 (1280×800×24)
2. Run: DISPLAY=:99 flutter run -d linux --release 2>/dev/null &
3. Wait 8 seconds for app to reach idle state
4. Capture: DISPLAY=:99 scrot -u <module>/docs/assets/screenshots/desktop-linux/01-home.png
5. If screenshots.yaml has steps, simulate keypresses/clicks via xdotool
6. Kill flutter process, stop XvfbLimitation: only captures the initial screen unless screenshots.yaml defines navigation steps using xdotool commands.
12.4.3 Mobile — Android (AVD + ADB)
Requirements: Android SDK, an AVD named koder-pixel7 (Pixel 7, API 34), flutter SDK.
1. Check if AVD is already running: adb devices
2. If not: emulator -avd koder-pixel7 -no-window -no-audio &
3. Wait for boot: adb wait-for-device && adb shell getprop sys.boot_completed == "1"
4. Run: flutter run -d emulator-XXXX --release &
5. Wait 10 seconds for app idle
6. Capture: adb exec-out screencap -p > 01-home.png
7. Crop to device frame (strip status bar if solid colour top 72px)
8. Save to <module>/docs/assets/screenshots/mobile-android/
9. Kill flutter process (emulator stays running for reuse across modules)12.4.4 Mobile — iOS (Simulator)
Requirements: macOS host with Xcode, an iOS simulator named iPhone 15. *nly runs on macOS*— skip silently on Linux.
xcrun simctl boot "iPhone 15"
flutter run -d "iPhone 15" --release &
sleep 10
xcrun simctl io booted screenshot <dest>/01-home.png12.5 screenshots.yaml — navigation steps and captions (optional)
If the file <module>/docs/assets/screenshots/screenshots.yaml exists, the capture pipeline reads it for navigation instructions and caption overrides. Format:
# screenshots.yaml
module: platform/id
url: https://id.koder.dev # override auto-detected URL
auth: # use credential key from meta/context/credentials/
key: koder-id-test-user
screens:
- id: home
caption: "Home — sign-in options"
steps: [] # just load the URL
- id: login
caption: "Email and password login"
steps:
- click: "[data-testid=email-login]"
- wait: networkidle
- id: dashboard
caption: "User dashboard after authentication"
steps:
- fill: "[name=email]"
value: "{{auth.email}}"
- fill: "[name=password]"
value: "{{auth.password}}"
- click: "[type=submit]"
- wait: networkidle
desktop_steps: # xdotool commands for Linux desktop
- xdotool key Tab # move focus
- sleep 0.5
- xdotool key Return # activate
mobile_steps: [] # ADB/simctl input events (future)If screenshots.yaml is absent, the pipeline captures only the initial landing screen (one screenshot per platform).
12.6 When to regenerate screenshots
Screenshots are *ot regenerated on every housekeep*— they are expensive (require running apps, emulators). The generator regenerates a platform's screenshots for a module only when:
--screenshotsflag is passed explicitly to the generation script- The module's
screenshots.yamlchanged since the last capture - The
<platform>/subfolder is empty or missing - The module's major version changed (detected from
koder.tomlorpubspec.yaml)
Otherwise, existing PNGs are reused as-is.
12.7 Embedding screenshots in documents
When generating a Manual or Slide Deck PDF for a module that has screenshots, the generator:
- Discovers all PNGs in
<module>/docs/assets/screenshots/recursively, sorted by subfolder then filename - For *anuals (USR/REF)* inserts a "Screenshots" section after the main content with one subsection per platform (Web · Desktop · Mobile). Each screenshot is full-width with a caption below.
- For *lide Decks* inserts a "UI Walkthrough" slide group — one slide per screenshot, with the caption as the slide title and the image filling 80% of the slide area.
- For *onsolidated PDFs* screenshots are embedded in the per-module section just like in Manuals.
CSS for screenshot embedding in portrait documents:
.screenshot-section h3 { font-size: 11pt; color: #64748b; margin: 24px 0 8px;
text-transform: uppercase; letter-spacing: .06em; }
.screenshot-wrap { margin: 12px 0 20px; }
.screenshot-img { max-width: 100%; border: 1px solid #e2e8f0;
border-radius: 8px; box-shadow: 0 2px 8px rgba(0,0,0,.08); }
.screenshot-caption { font-size: 9pt; color: #94a3b8; margin-top: 6px;
text-align: center; font-style: italic; }12.8 Image size limits
| Platform | Max width | Max file size |
|---|---|---|
| web-desktop | 1440px | 600 KB |
| web-tablet | 768px | 300 KB |
| web-mobile | 390px (2× retina → 780px) | 300 KB |
| desktop-linux | 1280px | 500 KB |
| mobile-android | 1080px (native) | 400 KB |
| mobile-ios | 1179px (iPhone 15 native) | 400 KB |
If a captured PNG exceeds the limit, compress with pngquant --quality=65-85 before saving.
12.9 What the generator must NOT do
- *nvent screenshots* if capture fails for any reason, log a warning and skip — do not embed a placeholder image.
- *apture production credentials* navigation steps that require login must use test accounts from
meta/context/credentials/. Never embed real user data in screenshots. - *apture external services* only capture UIs served by the module itself (local dev server or the module's own production URL). Do not screenshot third-party pages.
- *lock the housekeep on capture failure* screenshot capture failure is a warning, not an error — the rest of Phase 3 continues normally.
13. Diagram visual standard (D2)
All D2 diagrams under docs/stack/diagrams/ (aerial + perarea + flows + permodule) follow the same visual language so they feel like one family of illustrations when embedded in PDFs and slide decks. This section is the source of truth — docs/stack/build/build.sh and every .d2 file must conform.
13.1 Build command
Render every .d2 file with:
d2 --theme=0 --layout=elk --pad 100 <file>.d2 <file>.svg
rsvg-convert -w 3000 <file>.svg -o <file>.png- *-heme=0
** (Neutral Default, light) — fundo branco; containers e nós trazem a cor viastyle.fill` explícito. Não usar o theme 200 dark antigo. - *-ayout=elk
** (Eclipse Layout Kernel) — muito menos cruzamentos de arestas quedagre`; arestas ortogonais e hierarquia mais limpa. - *-ad 100`*— respiração lateral generosa; evita que sombras sejam cortadas.
- *asterização em 3000px*— nitidez em páginas A4 landscape de slide decks e no PDF técnico.
13.2 Shared classes (obrigatórias)
Todo .d2 com Áreas ou containers coloridos deve declarar o bloco classes abaixo no topo do arquivo, antes de qualquer nó. Isso é DRY: muda num lugar, aplica em todo canto.
classes: {
area: {
style: {
border-radius: 20
shadow: true
stroke-width: 0
font-size: 20
bold: true
font-color: "#ffffff"
}
}
node: {
style: {
border-radius: 12
stroke-width: 0
font-size: 15
font-color: "#0f172a"
fill: "#ffffff"
shadow: true
}
}
}Containers de Área aplicam class: area; módulos/nós dentro deles aplicam class: node. Nunca repetir style.fill, style.font-color, border-radius inline em cada nó — use as classes.
13.3 Gradient fill por Área
Cada Área tem um par de cores (escuro → claro) que formam o fundo via linear-gradient. Isso dá profundidade e coesão — cores chapadas são proibidas para containers de Área.
| Área | Gradient fill |
|---|---|
| Foundation | linear-gradient(#1e3a8a, #3b82f6) |
| Data Platform | linear-gradient(#0f766e, #14b8a6) |
| Cloud Infrastructure | linear-gradient(#0369a1, #0ea5e9) |
| Observability | linear-gradient(#6d28d9, #a855f7) |
| Intelligence | linear-gradient(#9f1239, #f43f5e) |
| Developer Platform | linear-gradient(#a16207, #eab308) |
| Workspace | linear-gradient(#166534, #22c55e) |
| Industry Solutions | linear-gradient(#9a3412, #f97316) |
| Brand & Presence | linear-gradient(#334155, #64748b) |
Aplicar no container de Área:
foundation: Foundation {
class: area
icon: /home/koder/dev/koder/sites/foundation/icon.svg
style.fill: "linear-gradient(#1e3a8a, #3b82f6)"
linux: Koder Linux {class: node; icon: /home/koder/dev/koder/linux/distro/icon.svg}
...
}13.4 Ícones embutidos nos nós
Cada container de Área recebe o ícone de sites/<area>/icon.svg (9 áreas têm todos). Cada nó de módulo recebe seu próprio icon.svg se existir; sem ícone, cai em pílula sótexto — *ão inventar placeholder* O `/khousekeep §1.6 já reporta módulos sem icon.svg` como ⚠️.
- Usar *aminho absoluto*(
/home/koder/dev/koder/...) — D2 v0.7 não aceita paths relativos paraicon:. - O ícone aparece no canto do container/nó (top-left) automaticamente.
13.5 Estilo das arestas
Default para todas as arestas:
style: {stroke: "#94a3b8"; stroke-width: 2}Arestas com label ("depends on", "authenticates", etc.) recebem estilo reforçado:
style: {stroke: "#475569"; stroke-width: 3; font-size: 14; font-color: "#334155"; bold: true}13.6 Título do diagrama
Toda .d2 começa com um título markdown no topo. Para aerial e áreas:
title: |md
# Koder Stack
## Aerial view — 9 areas · 50+ modules
| {near: top-center; shape: text; style.font-size: 36; style.bold: true; style.font-color: "#0f172a"}Fontes menores (26/22pt) para flows individuais. Cor sempre #0f172a (slate-900) para contraste em fundo branco.
13.7 Categorias de diagrama
| Categoria | Path | Estrutura | Classes usadas |
|---|---|---|---|
| Aerial | diagrams/aerial.d2 |
9 containers de Área, um por cor; módulos como pílulas; arestas inter-Área | area + node |
| Area | diagrams/areas/<area>.d2 |
1 container da Área com todos os módulos; arestas internas | area + node |
| Flow | diagrams/flows/<flow>.d2 |
Actors + etapas numeradas; sem containers de Área | só node (cor neutra ou cor da Área do actor) |
| Module | diagrams/modules/<module>.d2 |
Coupling deep-dive; nós = dependências externas | só node |
Para flows, actors de Áreas diferentes recebem style.fill individual com a cor sólida base da sua Área (não gradient — actors são pontos, não blocos). Exemplo: ator foundation/id → style.fill: "#1e3a8a"; style.font-color: white.
13.8 Proibições
- ❌ Tema dark (
--theme=200,--theme=201) — todos os diagramas são light. Inversão automática para dark mode dos PDFs fica para iteração futura. - ❌ Layout
dagre— sempreelk. - ❌
style.fillchapado em containers de Área — semprelinear-gradient. - ❌ Repetir estilo inline — sempre via
class. - ❌
icon.svgde placeholder ou genérico — só ícone real do módulo ou ausente. - ❌
stroke-width> 15 (limite do D2) ou < 1. - ❌ Fontes externas via
--font-regularenquanto não houver Inter/JetBrains instalados no host de build — ficar no Source Sans Pro default.
13.9 Regeneração
docs/stack/build/build.sh rerenderiza todos os housekeep §1.10.d2 para .svg + .png a cada execução do `/k. Os arquivos .svg e .png sob diagrams são **build artefacts gitignored** (docsstack.gitignore) — só o .d2 fonte entra no git. Após clone, rodar .build/build.sh` gera os assets localmente.
13.10 Pilot de referência
O diagrama canônico do estilo é docs/stack/diagrams/aerial.d2. Ao criar ou refatorar outro .d2, abrir o aerial como template e espelhar:
- Bloco
classesno topo - Título markdown com font-size 362622
- Containers com
class: area+icon:+style.fill: "linear-gradient(...)" - Nós com
class: node+icon:quando existir - Arestas com estilo neutro padrão (§13.5)